nitter.nim 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # SPDX-License-Identifier: AGPL-3.0-only
  2. import asyncdispatch, strformat
  3. from net import Port
  4. from htmlgen import a
  5. from os import getEnv
  6. import jester
  7. import types, config, prefs, formatters, redis_cache, http_pool, tokens
  8. import views/[general, about]
  9. import routes/[
  10. preferences, timeline, status, media, search, rss, list,
  11. unsupported, embed, resolver, router_utils]
  12. const instancesUrl = "https://github.com/zedeus/nitter/wiki/Instances"
  13. const issuesUrl = "https://github.com/zedeus/nitter/issues"
  14. let configPath = getEnv("NITTER_CONF_FILE", "./nitter.conf")
  15. let (cfg, fullCfg) = getConfig(configPath)
  16. when defined(release):
  17. import logging
  18. # Silence Jester's query warning
  19. addHandler(newConsoleLogger())
  20. setLogFilter(lvlError)
  21. stdout.write &"Starting Nitter at {getUrlPrefix(cfg)}\n"
  22. stdout.flushFile
  23. updateDefaultPrefs(fullCfg)
  24. setCacheTimes(cfg)
  25. setHmacKey(cfg.hmacKey)
  26. setProxyEncoding(cfg.base64Media)
  27. setMaxHttpConns(cfg.httpMaxConns)
  28. setHttpProxy(cfg.proxy, cfg.proxyAuth)
  29. waitFor initRedisPool(cfg)
  30. stdout.write &"Connected to Redis at {cfg.redisHost}:{cfg.redisPort}\n"
  31. stdout.flushFile
  32. asyncCheck initTokenPool(cfg)
  33. createUnsupportedRouter(cfg)
  34. createResolverRouter(cfg)
  35. createPrefRouter(cfg)
  36. createTimelineRouter(cfg)
  37. createListRouter(cfg)
  38. createStatusRouter(cfg)
  39. createSearchRouter(cfg)
  40. createMediaRouter(cfg)
  41. createEmbedRouter(cfg)
  42. createRssRouter(cfg)
  43. settings:
  44. port = Port(cfg.port)
  45. staticDir = cfg.staticDir
  46. bindAddr = cfg.address
  47. routes:
  48. get "/":
  49. resp renderMain(renderSearch(), request, cfg, themePrefs())
  50. get "/about":
  51. resp renderMain(renderAbout(), request, cfg, themePrefs())
  52. get "/explore":
  53. redirect("/about")
  54. get "/help":
  55. redirect("/about")
  56. get "/i/redirect":
  57. let url = decodeUrl(@"url")
  58. if url.len == 0: resp Http404
  59. redirect(replaceUrls(url, cookiePrefs()))
  60. error Http404:
  61. resp Http404, showError("Page not found", cfg)
  62. error InternalError:
  63. echo error.exc.name, ": ", error.exc.msg
  64. const link = a("open a GitHub issue", href = issuesUrl)
  65. resp Http500, showError(
  66. &"An error occurred, please {link} with the URL you tried to visit.", cfg)
  67. error RateLimitError:
  68. echo error.exc.name, ": ", error.exc.msg
  69. const link = a("another instance", href = instancesUrl)
  70. resp Http429, showError(
  71. &"Instance has been rate limited.<br>Use {link} or try again later.", cfg)
  72. extend unsupported, ""
  73. extend preferences, ""
  74. extend resolver, ""
  75. extend rss, ""
  76. extend search, ""
  77. extend timeline, ""
  78. extend list, ""
  79. extend status, ""
  80. extend media, ""
  81. extend embed, ""