Coverage for functions \ flipdare \ util \ public \ public_types.py: 97%

67 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-05-08 12:22 +1000

1#!/usr/bin/env python 

2# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved. 

3# 

4# This file is part of Flipdare's proprietary software and contains 

5# confidential and copyrighted material. Unauthorised copying, 

6# modification, distribution, or use of this file is strictly 

7# prohibited without prior written permission from Flipdare Pty Ltd. 

8# 

9# This software includes third-party components licensed under MIT, 

10# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details. 

11# 

12from __future__ import annotations 

13 

14from dataclasses import dataclass, field 

15from enum import StrEnum 

16from pathlib import Path 

17from flipdare.constants import ( 

18 FIREBASE_TMP_EMAIL_PATH, 

19 FIREBASE_EMAIL_RETENTION_DAYS, 

20 FIREBASE_TMP_RECEIPT_PATH, 

21 FIREBASE_RECEIPT_RETENTION_DAYS, 

22) 

23 

24__all__ = [ 

25 "PublicContentType", 

26 "PublicStoragePath", 

27 "PublicUrl", 

28 "PublicContent", 

29] 

30 

31 

32class PublicContentType(StrEnum): 

33 VIDEO = "video/mp4" 

34 # supported images 

35 JPEG = "image/jpeg" 

36 PNG = "image/png" 

37 WEBP = "image/webp" 

38 GIF = "image/gif" 

39 # receipts etc 

40 PDF = "application/pdf" 

41 # fallback 

42 OTHER = "application/octet-stream" 

43 

44 @staticmethod 

45 def guess(filename: str) -> PublicContentType: 

46 path = Path(filename) 

47 ext = path.suffix.lower().lstrip(".") 

48 match ext: 

49 case "mp4": 

50 return PublicContentType.VIDEO 

51 case "jpg" | "jpeg": 

52 return PublicContentType.JPEG 

53 case "png": 

54 return PublicContentType.PNG 

55 case "webp": 

56 return PublicContentType.WEBP 

57 case "gif": 

58 return PublicContentType.GIF 

59 case "pdf": 

60 return PublicContentType.PDF 

61 case _: 

62 return PublicContentType.OTHER 

63 

64 

65class PublicStoragePath(StrEnum): 

66 RECEIPTS = FIREBASE_TMP_RECEIPT_PATH 

67 EMAILS = FIREBASE_TMP_EMAIL_PATH 

68 

69 @property 

70 def retention_days(self) -> int: 

71 match self: 

72 case PublicStoragePath.RECEIPTS: 

73 return FIREBASE_RECEIPT_RETENTION_DAYS 

74 case PublicStoragePath.EMAILS: 

75 return FIREBASE_EMAIL_RETENTION_DAYS 

76 

77 

78@dataclass(frozen=True, kw_only=True) 

79class PublicUrl: 

80 file_name: str 

81 content_type: PublicContentType 

82 storage_path: PublicStoragePath 

83 

84 @property 

85 def remote_path(self) -> str: 

86 return f"{self.storage_path.value}/{self.file_name}" 

87 

88 

89@dataclass(frozen=True, kw_only=True) 

90class PublicContent: 

91 url: PublicUrl 

92 bytes_content: bytes = field(repr=False) 

93 

94 @property 

95 def file_name(self) -> str: 

96 return self.url.file_name 

97 

98 @property 

99 def remote_path(self) -> str: 

100 return self.url.remote_path 

101 

102 @property 

103 def content_type(self) -> PublicContentType: 

104 return self.url.content_type 

105 

106 @property 

107 def storage_path(self) -> PublicStoragePath: 

108 return self.url.storage_path