user.nim 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import std/[algorithm, unicode, re, strutils, strformat, options, nre]
  2. import jsony
  3. import utils, slices
  4. import ../types/user as userType
  5. from ../../types import User, Error
  6. let
  7. unRegex = re.re"(^|[^A-z0-9-_./?])@([A-z0-9_]{1,15})"
  8. unReplace = "$1<a href=\"/$2\">@$2</a>"
  9. htRegex = nre.re"""(*U)(^|[^\w-_.?])([##$])([\w_]*+)(?!</a>|">|#)"""
  10. htReplace = "$1<a href=\"/search?q=%23$3\">$2$3</a>"
  11. proc expandUserEntities(user: var User; raw: RawUser) =
  12. let
  13. orig = user.bio.toRunes
  14. ent = raw.entities
  15. if ent.url.urls.len > 0:
  16. user.website = ent.url.urls[0].expandedUrl
  17. var replacements = newSeq[ReplaceSlice]()
  18. for u in ent.description.urls:
  19. replacements.extractUrls(u, orig.high)
  20. replacements.dedupSlices
  21. replacements.sort(cmp)
  22. user.bio = orig.replacedWith(replacements, 0 .. orig.len)
  23. .replacef(unRegex, unReplace)
  24. .replace(htRegex, htReplace)
  25. proc getBanner(user: RawUser): string =
  26. if user.profileBannerUrl.len > 0:
  27. return user.profileBannerUrl & "/1500x500"
  28. if user.profileLinkColor.len > 0:
  29. return '#' & user.profileLinkColor
  30. if user.profileImageExtensions.isSome:
  31. let ext = get(user.profileImageExtensions)
  32. if ext.mediaColor.r.ok.palette.len > 0:
  33. let color = ext.mediaColor.r.ok.palette[0].rgb
  34. return &"#{color.red:02x}{color.green:02x}{color.blue:02x}"
  35. proc toUser*(raw: RawUser): User =
  36. result = User(
  37. id: raw.idStr,
  38. username: raw.screenName,
  39. fullname: raw.name,
  40. location: raw.location,
  41. bio: raw.description,
  42. following: raw.friendsCount,
  43. followers: raw.followersCount,
  44. tweets: raw.statusesCount,
  45. likes: raw.favouritesCount,
  46. media: raw.mediaCount,
  47. verified: raw.verified,
  48. protected: raw.protected,
  49. joinDate: parseTwitterDate(raw.createdAt),
  50. banner: getBanner(raw),
  51. userPic: getImageUrl(raw.profileImageUrlHttps).replace("_normal", "")
  52. )
  53. if raw.pinnedTweetIdsStr.len > 0:
  54. result.pinnedTweet = parseBiggestInt(raw.pinnedTweetIdsStr[0])
  55. result.expandUserEntities(raw)
  56. proc parseUser*(json: string; username=""): User =
  57. handleErrors:
  58. case error.code
  59. of suspended: return User(username: username, suspended: true)
  60. of userNotFound: return
  61. else: echo "[error - parseUser]: ", error
  62. result = toUser json.fromJson(RawUser)