Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/prop/image.py: 33%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

43 statements  

1"""This contains the IMAGE property from :rfc:`7986`.""" 

2 

3from __future__ import annotations 

4 

5import base64 

6from typing import TYPE_CHECKING 

7 

8from icalendar.prop.binary import vBinary 

9from icalendar.prop.uri import vUri 

10 

11if TYPE_CHECKING: 

12 from icalendar.prop.text import vText 

13 

14 

15class Image: 

16 """An image as URI or BINARY according to :rfc:`7986`. 

17 

18 Value Type: 

19 URI or BINARY -- no default. The value MUST be data 

20 with a media type of "image" or refer to such data. 

21 

22 Description: 

23 This property specifies an image for an iCalendar 

24 object or a calendar component via a URI or directly with inline 

25 data that can be used by calendar user agents when presenting the 

26 calendar data to a user. Multiple properties MAY be used to 

27 specify alternative sets of images with, for example, varying 

28 media subtypes, resolutions, or sizes. When multiple properties 

29 are present, calendar user agents SHOULD display only one of them, 

30 picking one that provides the most appropriate image quality, or 

31 display none. The "DISPLAY" parameter is used to indicate the 

32 intended display mode for the image. The "ALTREP" parameter, 

33 defined in :rfc:`5545`, can be used to provide a "clickable" image 

34 where the URI in the parameter value can be "launched" by a click 

35 on the image in the calendar user agent. 

36 

37 Parameters: 

38 uri: The URI of the image. 

39 b64data: The data of the image, base64 encoded. 

40 fmttype: The format type, e.g. ``"image/png"``. 

41 altrep: Link target of the image. 

42 display: The display mode, e.g. ``"BADGE"``. 

43 

44 """ 

45 

46 @classmethod 

47 def from_property_value(cls, value: vUri | vBinary | vText) -> Image: 

48 """Create an Image from a property value.""" 

49 params: dict[str, str] = {} 

50 if not hasattr(value, "params"): 

51 raise TypeError("Value must be URI or BINARY.") 

52 try: 

53 value_type = value.params.get("VALUE", "").upper() 

54 except (AttributeError, TypeError) as err: 

55 raise TypeError("Value must have a valid params attribute.") from err 

56 if value_type == "URI" or isinstance(value, vUri): 

57 params["uri"] = str(value) 

58 elif isinstance(value, vBinary): 

59 params["b64data"] = value.obj 

60 elif value_type == "BINARY": 

61 params["b64data"] = str(value) 

62 else: 

63 raise TypeError( 

64 f"The VALUE parameter must be URI or BINARY, not {value_type!r}." 

65 ) 

66 params.update( 

67 { 

68 "fmttype": value.params.get("FMTTYPE"), 

69 "altrep": value.params.get("ALTREP"), 

70 "display": value.params.get("DISPLAY"), 

71 } 

72 ) 

73 return cls(**params) 

74 

75 def __init__( 

76 self, 

77 uri: str | None = None, 

78 b64data: str | None = None, 

79 fmttype: str | None = None, 

80 altrep: str | None = None, 

81 display: str | None = None, 

82 ) -> None: 

83 """Create a new image according to :rfc:`7986`.""" 

84 if uri is not None and b64data is not None: 

85 raise ValueError("Image cannot have both URI and binary data (RFC 7986)") 

86 if uri is None and b64data is None: 

87 raise ValueError("Image must have either URI or binary data") 

88 self.uri = uri 

89 self.b64data = b64data 

90 self.fmttype = fmttype 

91 self.altrep = altrep 

92 self.display = display 

93 

94 @property 

95 def data(self) -> bytes | None: 

96 """Return the binary data, if available.""" 

97 if self.b64data is None: 

98 return None 

99 return base64.b64decode(self.b64data) 

100 

101 

102__all__ = ["Image"]