import fsspec import os from django.conf import settings from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from dataclasses import dataclass from rest_framework.response import Response from rest_framework.mixins import ListModelMixin from rest_framework.viewsets import GenericViewSet from rest_framework_dataclasses.serializers import DataclassSerializer from typing import List from urllib.parse import urlparse @dataclass class AppVersion: version: str plugins: List[str] class AppVersionSerializer(DataclassSerializer): class Meta: dataclass = AppVersion class AppVersionViewSet(ListModelMixin, GenericViewSet): serializer_class = AppVersionSerializer lookup_field = "id" lookup_value_regex = r"[\w\d.-]+" queryset = "" def _get_versions(self): fs = fsspec.filesystem(urlparse(settings.APP_DIST_STORAGE).scheme) return [ self._get_version(x["name"]) for x in fs.listdir(settings.APP_DIST_STORAGE) if x["type"] == "directory" ] def _get_version(self, dir): fs = fsspec.filesystem(urlparse(settings.APP_DIST_STORAGE).scheme) plugins = [ os.path.basename(x["name"]) for x in fs.listdir(dir) if x["type"] == "directory" and os.path.basename(x["name"]) not in [ "tabby-web-container", "tabby-web-demo", ] ] return AppVersion( version=os.path.basename(dir), plugins=plugins, ) @method_decorator(cache_page(60)) def list(self, request, *args, **kwargs): return Response( self.serializer_class( self._get_versions(), many=True, ).data )