nitter.nim 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import asyncdispatch, httpclient, times, strutils, hashes, random, uri
  2. import jester, regex
  3. import api, utils, types, cache
  4. import views/[user, general, conversation]
  5. proc showTimeline(name: string; num=""): Future[string] {.async.} =
  6. let
  7. username = name.strip(chars={'/'})
  8. profileFut = getCachedProfile(username)
  9. tweetsFut = getTimeline(username, after=num)
  10. let profile = await profileFut
  11. if profile.username.len == 0:
  12. return ""
  13. return renderMain(renderProfile(profile, await tweetsFut, num.len == 0))
  14. routes:
  15. get "/":
  16. resp renderMain(renderSearchPanel())
  17. post "/search":
  18. if @"query".len == 0:
  19. resp Http404, showError("Please enter a username.")
  20. redirect("/" & @"query")
  21. get "/@name/?":
  22. cond '.' notin @"name"
  23. let timeline = await showTimeline(@"name", @"after")
  24. if timeline.len == 0:
  25. resp Http404, showError("User \"" & @"name" & "\" not found")
  26. resp timeline
  27. get "/@name/status/@id":
  28. cond '.' notin @"name"
  29. let conversation = await getTweet(@"id")
  30. if conversation.tweet.id.len == 0:
  31. resp Http404, showError("Tweet not found")
  32. resp renderMain(renderConversation(conversation))
  33. get "/pic/@sig/@url":
  34. cond "http" in @"url"
  35. cond "twimg" in @"url"
  36. let url = decodeUrl(@"url")
  37. if getHmac(url) != @"sig":
  38. resp showError("Failed to verify signature")
  39. let
  40. client = newAsyncHttpClient()
  41. pic = await client.getContent(url)
  42. defer: client.close()
  43. resp pic, mimetype(url)
  44. get "/video/@sig/@url":
  45. cond "http" in @"url"
  46. cond "video.twimg" in @"url"
  47. let url = decodeUrl(@"url")
  48. if getHmac(url) != @"sig":
  49. resp showError("Failed to verify signature")
  50. let
  51. client = newAsyncHttpClient()
  52. pic = await client.getContent(url)
  53. defer: client.close()
  54. resp pic, mimetype(url)
  55. runForever()