"""Представления (views) приложения `cv`.""" from typing import Any from django.http import FileResponse, Http404, HttpRequest from django.views.generic.base import TemplateView, View from cv.models import Profile from cv.services.dowload.docx import DocxRenderer from cv.services.dowload.pdf import PdfRenderer class ProfileView(TemplateView): """Отображение профиля на главной странице.""" template_name = "index.html" extra_context = {} def get_context_data(self, **kwargs: Any) -> dict[str, Any]: """Собрать контекст для шаблона. Args: **kwargs: Дополнительные параметры контекста. Returns: dict: Словарь контекста для рендеринга шаблона. """ kwargs.setdefault("view", self) extra_context = self._get_extra_context() self.extra_context.update(extra_context) if self.extra_context is not None: kwargs.update(self.extra_context) return kwargs def _get_extra_context(self) -> dict[str, Any]: """Получить дополнительные данные для контекста (профиль и связанные сущности). Returns: dict: Дополнительные пары ключ/значение для контекста. Raises: Http404: Если профиль не найден. """ profile = Profile.objects.prefetch_related("experience", "skills_map").first() if not profile: raise Http404("Профиль не найден") return { "profile": profile, } class DownloadDocxView(View): """Скачать резюме в формате DOCX.""" _docx = DocxRenderer() def get(self, _request: HttpRequest, *_args: Any, **_kwargs: Any) -> FileResponse: """Вернуть файл DOCX с содержимым резюме. Args: request: HTTP‑запрос. *args: Позиционные аргументы. **kwargs: Именованные аргументы. Returns: FileResponse: Ответ c приложением DOCX. Raises: Http404: Если профиль не найден. """ profile = Profile.objects.prefetch_related("experience", "skills_map").first() if not profile: raise Http404("Профиль не найден") buffer = self._docx.render(profile) safe_utf8 = f"resume_{profile.full_name.replace(' ', '_')}.docx" buffer.seek(0) resp = FileResponse( buffer, as_attachment=True, filename=safe_utf8, content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document", ) resp["Cache-Control"] = "no-store" return resp class DownloadPdfView(View): """Скачать резюме в формате PDF.""" _pdf = PdfRenderer() def get(self, _request: HttpRequest, *_args: Any, **_kwargs: Any) -> FileResponse: """Вернуть файл PDF с содержимым резюме. Args: request: HTTP‑запрос. *args: Позиционные аргументы. **kwargs: Именованные аргументы. Returns: FileResponse: Ответ c приложением PDF. Raises: Http404: Если профиль не найден. """ profile = Profile.objects.prefetch_related("experience", "skills_map").first() if not profile: raise Http404("Профиль не найден") stream = self._pdf.render(profile) safe_utf8 = f"resume_{profile.full_name.replace(' ', '_')}.pdf" resp = FileResponse( stream, as_attachment=True, filename=safe_utf8, content_type="application/pdf", ) resp["Cache-Control"] = "no-store" return resp