import mimetypes from django.http import FileResponse, Http404 from django.shortcuts import get_object_or_404 from django.views import View from django.views.generic import DetailView, ListView, TemplateView from .models import Article, ArticleCitation, ArticleSection, MainProduct, ProductVideo, SubProduct, SubProductVersion from .release_assets import FILE_FIELD_BY_ASSET_KEY, RELEASE_ASSET_KEYS, URL_FIELD_BY_ASSET_KEY from .release_context import build_archive_context, build_release_context class ReleaseAssetDownloadView(View): def get(self, request, version_id, asset): if asset not in RELEASE_ASSET_KEYS: raise Http404 version = get_object_or_404(SubProductVersion, pk=version_id, is_active=True) parent = version.sub_product or version.main_product if parent is None or not parent.is_active: raise Http404 url_field = URL_FIELD_BY_ASSET_KEY[asset] if (getattr(version, url_field) or "").strip(): raise Http404 file_field = FILE_FIELD_BY_ASSET_KEY[asset] release_file = getattr(version, file_field) if not release_file: raise Http404 filename = version.release_download_filename(asset) content_type, _ = mimetypes.guess_type(filename) return FileResponse( release_file.open("rb"), as_attachment=True, filename=filename, content_type=content_type or "application/octet-stream", ) class ProductOverviewView(ListView): model = MainProduct template_name = "products/overview.html" context_object_name = "main_products" queryset = MainProduct.objects.filter(is_active=True).prefetch_related( "sub_products" ) class MainProductDetailView(DetailView): model = MainProduct template_name = "products/main_detail.html" context_object_name = "main_product" slug_url_kwarg = "main_slug" queryset = MainProduct.objects.filter(is_active=True).prefetch_related( "sub_products" ) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["articles"] = self.object.articles.prefetch_related( "sections", "citations" ).all() context["product_videos"] = self.object.videos.filter(is_active=True).order_by("order") release_context = build_release_context( self.object.distribution, self.object.versions.filter(is_active=True), self.object, ) release_context["versions_archive_url"] = self.object.get_versions_archive_url() context.update(release_context) return context class MainProductOlderVersionsView(TemplateView): template_name = "products/versions_archive.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) main_product = get_object_or_404( MainProduct, slug=self.kwargs["main_slug"], is_active=True, ) active_versions = main_product.versions.filter(is_active=True) context["main_product"] = main_product context["sub_product"] = None context["product_detail_url"] = main_product.get_absolute_url() context.update( build_archive_context( main_product.distribution, active_versions, main_product ) ) return context class SubProductDetailView(TemplateView): template_name = "products/sub_detail.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) main_product = get_object_or_404( MainProduct, slug=self.kwargs["main_slug"], is_active=True, ) sub_product = get_object_or_404( SubProduct, slug=self.kwargs["sub_slug"], main_product=main_product, is_active=True, ) context["main_product"] = main_product context["sub_product"] = sub_product context["articles"] = sub_product.articles.prefetch_related( "sections", "citations" ).all() context["product_videos"] = sub_product.videos.filter(is_active=True).order_by("order") context["siblings"] = ( SubProduct.objects.filter(main_product=main_product, is_active=True) .exclude(pk=sub_product.pk) .order_by("order", "name") ) active_versions = sub_product.versions.filter(is_active=True) release_context = build_release_context( sub_product.distribution, active_versions, sub_product ) release_context["versions_archive_url"] = sub_product.get_versions_archive_url() context.update(release_context) return context class SubProductOlderVersionsView(TemplateView): template_name = "products/versions_archive.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) main_product = get_object_or_404( MainProduct, slug=self.kwargs["main_slug"], is_active=True, ) sub_product = get_object_or_404( SubProduct, slug=self.kwargs["sub_slug"], main_product=main_product, is_active=True, ) active_versions = sub_product.versions.filter(is_active=True) context["main_product"] = main_product context["sub_product"] = sub_product context["product_detail_url"] = sub_product.get_absolute_url() context.update( build_archive_context( sub_product.distribution, active_versions, sub_product ) ) return context