Coverage for src/paperap/resources/document_download.py: 42%
31 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-20 13:17 -0400
« prev ^ index » next coverage.py v7.6.12, created at 2025-03-20 13:17 -0400
1"""
2----------------------------------------------------------------------------
4 METADATA:
6 File: documents.py
7 Project: paperap
8 Created: 2025-03-04
9 Version: 0.0.8
10 Author: Jess Mann
11 Email: jess@jmann.me
12 Copyright (c) 2025 Jess Mann
14----------------------------------------------------------------------------
16 LAST MODIFIED:
18 2025-03-04 By Jess Mann
20"""
22from __future__ import annotations
24from typing import Any
26from typing_extensions import TypeVar
28from paperap.const import URLS
29from paperap.exceptions import APIError, BadResponseError, ResourceNotFoundError
30from paperap.models.document.download import DownloadedDocument, DownloadedDocumentQuerySet, RetrieveFileMode
31from paperap.resources.base import BaseResource, StandardResource
34class DownloadedDocumentResource(StandardResource[DownloadedDocument, DownloadedDocumentQuerySet]):
35 """Resource for managing downloaded document content."""
37 model_class = DownloadedDocument
38 queryset_class = DownloadedDocumentQuerySet
39 name = "document"
40 endpoints = {
41 RetrieveFileMode.PREVIEW: URLS.preview,
42 RetrieveFileMode.THUMBNAIL: URLS.thumbnail,
43 RetrieveFileMode.DOWNLOAD: URLS.download,
44 }
46 def load(self, downloaded_document: "DownloadedDocument") -> None:
47 """
48 Load the document file content from the API.
50 This method fetches the binary content of the document file
51 and updates the model with the response data.
52 """
53 mode = downloaded_document.mode or RetrieveFileMode.DOWNLOAD
54 endpoint = self.endpoints[mode]
56 params = {
57 "original": "true" if downloaded_document.original else "false",
58 }
60 if not (response := self.client.request_raw("GET", endpoint, params=params, data=None)):
61 raise ResourceNotFoundError(f"Unable to retrieve downloaded docuyment {downloaded_document.id}")
63 content = response.content
64 content_type = response.headers.get("Content-Type")
65 content_disposition = response.headers.get("Content-Disposition")
66 disposition_filename = None
67 disposition_type = None
69 # Parse Content-Disposition header
70 if content_disposition:
71 parts = content_disposition.split(";")
72 disposition_type = parts[0].strip()
74 for part in parts[1:]:
75 if "filename=" in part:
76 filename_part = part.strip()
77 disposition_filename = filename_part.split("=", 1)[1].strip("\"'")
79 # Update model
80 downloaded_document.update_locally(
81 from_db=True,
82 content=content,
83 content_type=content_type,
84 disposition_filename=disposition_filename,
85 disposition_type=disposition_type,
86 )