versioncheck.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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 * 8 # 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. api_url = "https://pypi.org/pypi/Misago/json"
  43. r = requests.get(api_url)
  44. r.raise_for_status()
  45. data = r.json()["info"]["version"]
  46. cache.set(CACHE_KEY, data, CACHE_LENGTH)
  47. return data
  48. def compare_versions(current, latest):
  49. if latest == current:
  50. return {
  51. "status": Status.SUCCESS,
  52. "message": _("The site is running updated version of Misago."),
  53. "description": _("Misago %(version)s is latest release.")
  54. % {"version": current},
  55. }
  56. return {
  57. "status": Status.ERROR,
  58. "message": _("The site is running outdated version of Misago."),
  59. "description": _(
  60. "The site is running Misago version %(version)s while version %(latest)s "
  61. "is available."
  62. )
  63. % {"version": current, "latest": latest},
  64. }