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

1""" 

2---------------------------------------------------------------------------- 

3 

4 METADATA: 

5 

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 

13 

14---------------------------------------------------------------------------- 

15 

16 LAST MODIFIED: 

17 

18 2025-03-04 By Jess Mann 

19 

20""" 

21 

22from __future__ import annotations 

23 

24from typing import Any 

25 

26from typing_extensions import TypeVar 

27 

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 

32 

33 

34class DownloadedDocumentResource(StandardResource[DownloadedDocument, DownloadedDocumentQuerySet]): 

35 """Resource for managing downloaded document content.""" 

36 

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 } 

45 

46 def load(self, downloaded_document: "DownloadedDocument") -> None: 

47 """ 

48 Load the document file content from the API. 

49 

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] 

55 

56 params = { 

57 "original": "true" if downloaded_document.original else "false", 

58 } 

59 

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}") 

62 

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 

68 

69 # Parse Content-Disposition header 

70 if content_disposition: 

71 parts = content_disposition.split(";") 

72 disposition_type = parts[0].strip() 

73 

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("\"'") 

78 

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 )