types.nim 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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
  12. ApiUrl* = object
  13. endpoint*: string
  14. params*: seq[(string, string)]
  15. ApiReq* = object
  16. oauth*: ApiUrl
  17. cookie*: ApiUrl
  18. RateLimit* = object
  19. limit*: int
  20. remaining*: int
  21. reset*: int
  22. SessionKind* = enum
  23. oauth
  24. cookie
  25. Session* = ref object
  26. id*: int64
  27. username*: string
  28. pending*: int
  29. limited*: bool
  30. limitedAt*: int
  31. apis*: Table[string, RateLimit]
  32. case kind*: SessionKind
  33. of oauth:
  34. oauthToken*: string
  35. oauthSecret*: string
  36. of cookie:
  37. authToken*: string
  38. ct0*: string
  39. Error* = enum
  40. null = 0
  41. noUserMatches = 17
  42. protectedUser = 22
  43. missingParams = 25
  44. timeout = 29
  45. couldntAuth = 32
  46. doesntExist = 34
  47. unauthorized = 37
  48. invalidParam = 47
  49. userNotFound = 50
  50. suspended = 63
  51. rateLimited = 88
  52. expiredToken = 89
  53. listIdOrSlug = 112
  54. tweetNotFound = 144
  55. tweetNotAuthorized = 179
  56. forbidden = 200
  57. badRequest = 214
  58. badToken = 239
  59. locked = 326
  60. noCsrf = 353
  61. tweetUnavailable = 421
  62. tweetCensored = 422
  63. VerifiedType* = enum
  64. none = "None"
  65. blue = "Blue"
  66. business = "Business"
  67. government = "Government"
  68. User* = object
  69. id*: string
  70. username*: string
  71. fullname*: string
  72. location*: string
  73. website*: string
  74. bio*: string
  75. userPic*: string
  76. banner*: string
  77. pinnedTweet*: int64
  78. following*: int
  79. followers*: int
  80. tweets*: int
  81. likes*: int
  82. media*: int
  83. verifiedType*: VerifiedType
  84. protected*: bool
  85. suspended*: bool
  86. joinDate*: DateTime
  87. AccountInfo* = object
  88. username*: string
  89. fullname*: string
  90. userPic*: string
  91. joinDate*: DateTime
  92. verifiedType*: VerifiedType
  93. suspended*: bool
  94. basedIn*: string
  95. source*: string
  96. usernameChanges*: int
  97. lastUsernameChange*: DateTime
  98. affiliateUsername*: string
  99. affiliateLabel*: string
  100. isIdentityVerified*: bool
  101. verifiedSince*: DateTime
  102. overrideVerifiedYear*: int
  103. Broadcast* = object
  104. id*: string
  105. title*: string
  106. state*: string
  107. thumb*: string
  108. mediaKey*: string
  109. m3u8Url*: string
  110. totalWatched*: int
  111. startTime*: DateTime
  112. endTime*: DateTime
  113. replayStart*: int
  114. availableForReplay*: bool
  115. user*: User
  116. VideoType* = enum
  117. m3u8 = "application/x-mpegURL"
  118. mp4 = "video/mp4"
  119. vmap = "video/vmap"
  120. VideoVariant* = object
  121. contentType*: VideoType
  122. url*: string
  123. bitrate*: int
  124. resolution*: int
  125. Video* = object
  126. durationMs*: int
  127. url*: string
  128. thumb*: string
  129. available*: bool
  130. reason*: string
  131. title*: string
  132. description*: string
  133. playbackType*: VideoType
  134. variants*: seq[VideoVariant]
  135. QueryKind* = enum
  136. posts, replies, media, users, tweets, userList
  137. Query* = object
  138. kind*: QueryKind
  139. view*: string
  140. text*: string
  141. filters*: seq[string]
  142. includes*: seq[string]
  143. excludes*: seq[string]
  144. fromUser*: seq[string]
  145. since*: string
  146. until*: string
  147. minLikes*: string
  148. sep*: string
  149. Gif* = object
  150. url*: string
  151. thumb*: string
  152. altText*: string
  153. Photo* = object
  154. url*: string
  155. altText*: string
  156. MediaKind* = enum
  157. photoMedia
  158. videoMedia
  159. gifMedia
  160. Media* = object
  161. case kind*: MediaKind
  162. of photoMedia:
  163. photo*: Photo
  164. of videoMedia:
  165. video*: Video
  166. of gifMedia:
  167. gif*: Gif
  168. MediaEntities* = seq[Media]
  169. GalleryPhoto* = object
  170. url*: string
  171. tweetId*: string
  172. color*: string
  173. PhotoRail* = seq[GalleryPhoto]
  174. Poll* = object
  175. options*: seq[string]
  176. values*: seq[int]
  177. votes*: int
  178. leader*: int
  179. status*: string
  180. CardKind* = enum
  181. amplify = "amplify"
  182. app = "app"
  183. appPlayer = "appplayer"
  184. player = "player"
  185. summary = "summary"
  186. summaryLarge = "summary_large_image"
  187. promoWebsite = "promo_website"
  188. promoVideo = "promo_video_website"
  189. promoVideoConvo = "promo_video_convo"
  190. promoImageConvo = "promo_image_convo"
  191. promoImageApp = "promo_image_app"
  192. storeLink = "direct_store_link_app"
  193. liveEvent = "live_event"
  194. broadcast = "broadcast"
  195. periscope = "periscope_broadcast"
  196. unified = "unified_card"
  197. moment = "moment"
  198. messageMe = "message_me"
  199. videoDirectMessage = "video_direct_message"
  200. imageDirectMessage = "image_direct_message"
  201. audiospace = "audiospace"
  202. newsletterPublication = "newsletter_publication"
  203. jobDetails = "job_details"
  204. hidden
  205. unknown
  206. Card* = object
  207. kind*: CardKind
  208. url*: string
  209. title*: string
  210. dest*: string
  211. text*: string
  212. image*: string
  213. video*: Option[Video]
  214. TweetStats* = object
  215. replies*: int
  216. retweets*: int
  217. likes*: int
  218. views*: int
  219. Tweet* = ref object
  220. id*: int64
  221. threadId*: int64
  222. replyId*: int64
  223. user*: User
  224. text*: string
  225. time*: DateTime
  226. reply*: seq[string]
  227. pinned*: bool
  228. hasThread*: bool
  229. available*: bool
  230. tombstone*: string
  231. location*: string
  232. # Unused, needed for backwards compat
  233. source*: string
  234. stats*: TweetStats
  235. retweet*: Option[Tweet]
  236. attribution*: Option[User]
  237. mediaTags*: seq[User]
  238. quote*: Option[Tweet]
  239. card*: Option[Card]
  240. poll*: Option[Poll]
  241. media*: MediaEntities
  242. history*: seq[int64]
  243. note*: string
  244. isAd*: bool
  245. isAI*: bool
  246. Tweets* = seq[Tweet]
  247. Result*[T] = object
  248. content*: seq[T]
  249. top*, bottom*: string
  250. beginning*: bool
  251. query*: Query
  252. Chain* = object
  253. content*: Tweets
  254. hasMore*: bool
  255. cursor*: string
  256. Conversation* = ref object
  257. tweet*: Tweet
  258. before*: Chain
  259. after*: Chain
  260. replies*: Result[Chain]
  261. EditHistory* = object
  262. latest*: Tweet
  263. history*: Tweets
  264. Timeline* = Result[Tweets]
  265. Profile* = object
  266. user*: User
  267. photoRail*: PhotoRail
  268. pinned*: Option[Tweet]
  269. tweets*: Timeline
  270. accountInfo*: AccountInfo
  271. List* = object
  272. id*: string
  273. name*: string
  274. userId*: string
  275. username*: string
  276. description*: string
  277. members*: int
  278. banner*: string
  279. GlobalObjects* = ref object
  280. tweets*: Table[string, Tweet]
  281. users*: Table[string, User]
  282. Config* = ref object
  283. address*: string
  284. port*: int
  285. useHttps*: bool
  286. httpMaxConns*: int
  287. title*: string
  288. hostname*: string
  289. staticDir*: string
  290. hmacKey*: string
  291. base64Media*: bool
  292. minTokens*: int
  293. enableRSSUserTweets*: bool
  294. enableRSSUserReplies*: bool
  295. enableRSSUserMedia*: bool
  296. enableRSSSearch*: bool
  297. enableRSSList*: bool
  298. enableDebug*: bool
  299. proxy*: string
  300. proxyAuth*: string
  301. apiProxy*: string
  302. disableTid*: bool
  303. maxConcurrentReqs*: int
  304. maxRetries*: int
  305. retryDelayMs*: int
  306. rssCacheTime*: int
  307. listCacheTime*: int
  308. redisHost*: string
  309. redisPort*: int
  310. redisConns*: int
  311. redisMaxConns*: int
  312. redisPassword*: string
  313. Rss* = object
  314. feed*, cursor*: string
  315. proc contains*(thread: Chain; tweet: Tweet): bool =
  316. thread.content.anyIt(it.id == tweet.id)
  317. proc add*(timeline: var seq[Tweets]; tweet: Tweet) =
  318. timeline.add @[tweet]
  319. proc getPhotos*(tweet: Tweet): seq[Photo] =
  320. tweet.media.filterIt(it.kind == photoMedia).mapIt(it.photo)
  321. proc getVideos*(tweet: Tweet): seq[Video] =
  322. tweet.media.filterIt(it.kind == videoMedia).mapIt(it.video)
  323. proc hasPhotos*(tweet: Tweet): bool =
  324. tweet.media.anyIt(it.kind == photoMedia)
  325. proc hasVideos*(tweet: Tweet): bool =
  326. tweet.media.anyIt(it.kind == videoMedia)
  327. proc hasGifs*(tweet: Tweet): bool =
  328. tweet.media.anyIt(it.kind == gifMedia)
  329. proc getThumb*(media: Media): string =
  330. case media.kind
  331. of photoMedia: media.photo.url
  332. of videoMedia: media.video.thumb
  333. of gifMedia: media.gif.thumb