from django.conf import settings from django.core.cache import cache from django.utils import timezone from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.views import APIView APP_VERSION_CACHE_KEY = "app_version:latest" def _coerce_version_part(value) -> int: return max(0, int(value or 0)) def _coerce_publish_date(value) -> str: return str(value or timezone.localdate().isoformat()).strip() def build_app_version_payload( *, major, minor, build, download_url: str, force=False, publish_date=None, ) -> dict: return { "latest_version": { "major": _coerce_version_part(major), "minor": _coerce_version_part(minor), "build": _coerce_version_part(build), }, "download_url": str(download_url or "").strip(), "force": bool(force), "publish_date": _coerce_publish_date(publish_date), } def get_app_version_payload() -> dict: cached_payload = cache.get(APP_VERSION_CACHE_KEY) if isinstance(cached_payload, dict): try: version = cached_payload["latest_version"] return build_app_version_payload( major=version["major"], minor=version["minor"], build=version["build"], download_url=cached_payload.get("download_url", ""), force=cached_payload["force"], publish_date=cached_payload["publish_date"], ) except (KeyError, TypeError, ValueError): pass return build_app_version_payload( major=getattr(settings, "APP_LATEST_VERSION_MAJOR", 0), minor=getattr(settings, "APP_LATEST_VERSION_MINOR", 0), build=getattr(settings, "APP_LATEST_VERSION_BUILD", 0), download_url=getattr(settings, "APP_DOWNLOAD_URL", ""), force=getattr(settings, "APP_FORCE_UPDATE", False), publish_date=getattr(settings, "APP_PUBLISH_DATE", None), ) def set_cached_app_version_payload( *, major, minor, build, download_url: str, force=False, publish_date=None, ) -> dict: payload = build_app_version_payload( major=major, minor=minor, build=build, download_url=download_url, force=force, publish_date=publish_date, ) cache.set(APP_VERSION_CACHE_KEY, payload, timeout=None) return payload class AppVersionView(APIView): permission_classes = [AllowAny] def get(self, request): return Response(get_app_version_payload())