versioncheck.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import requests
  2. from ariadne import QueryType
  3. from django.core.cache import cache
  4. from django.utils.translation import gettext as _
  5. from requests.exceptions import RequestException
  6. from ... import __released__, __version__
  7. from .status import Status
  8. CACHE_KEY = "misago_admin_version_check"
  9. CACHE_LENGTH = 3600 * 4 # 4 hours
  10. version_check = QueryType()
  11. @version_check.field("version")
  12. def resolve_version(*_):
  13. if not __released__:
  14. return get_unreleased_error()
  15. return check_version_with_api()
  16. def get_unreleased_error():
  17. return {
  18. "status": Status.ERROR,
  19. "message": _("The site is running using unreleased version of Misago."),
  20. "description": _(
  21. "Unreleased versions of Misago can lack security features and there is "
  22. "no supported way to upgrade them to release versions later."
  23. ),
  24. }
  25. def check_version_with_api():
  26. try:
  27. latest_version = get_latest_version()
  28. return compare_versions(__version__, latest_version)
  29. except (RequestException, KeyError, ValueError):
  30. return {
  31. "status": Status.WARNING,
  32. "message": _("Failed to connect to pypi.org API. Try again later."),
  33. "description": _(
  34. "Version check feature relies on the API operated by the Python "
  35. "Package Index (pypi.org) API to retrieve latest Misago release "
  36. "version."
  37. ),
  38. }
  39. def get_latest_version():
  40. data = cache.get(CACHE_KEY)
  41. if not data:
  42. data = get_latest_version_from_api()
  43. cache.set(CACHE_KEY, data, CACHE_LENGTH)
  44. return data
  45. def get_latest_version_from_api():
  46. api_url = "https://pypi.org/pypi/Misago/json"
  47. r = requests.get(api_url)
  48. r.raise_for_status()
  49. return r.json()["info"]["version"]
  50. def compare_versions(current, latest):
  51. if latest == current:
  52. return {
  53. "status": Status.SUCCESS,
  54. "message": _("The site is running updated version of Misago."),
  55. "description": _("Misago %(version)s is latest release.")
  56. % {"version": current},
  57. }
  58. return {
  59. "status": Status.ERROR,
  60. "message": _("The site is running outdated version of Misago."),
  61. "description": _(
  62. "The site is running Misago version %(version)s while version %(latest)s "
  63. "is available."
  64. )
  65. % {"version": current, "latest": latest},
  66. }