Source code for icalendar.prop.binary

"""BINARY values from :rfc:`5545`."""

import base64
import binascii
from typing import ClassVar

from icalendar.compatibility import Self, deprecate_for_version_8
from icalendar.error import JCalParsingError
from icalendar.parser import Parameters
from icalendar.parser_tools import to_unicode


[docs] class vBinary: """Binary property values are base 64 encoded.""" default_value: ClassVar[str] = "BINARY" bytes: bytes def __init__(self, obj: str | bytes, params: dict[str, str] | None = None) -> None: if isinstance(obj, str): self.bytes = obj.encode("utf-8") else: self.bytes = obj self.params = Parameters(encoding="BASE64", value="BINARY") if params: self.params.update(params) def __repr__(self) -> str: return f"vBinary({self.to_ical()})"
[docs] def to_ical(self) -> bytes: return base64.b64encode(self.bytes)
[docs] @staticmethod def from_ical(ical: str | bytes) -> bytes: try: return base64.b64decode(ical, validate=True) except (binascii.Error, ValueError) as e: raise ValueError("Not valid base 64 encoding.") from e
@property @deprecate_for_version_8 def obj(self) -> str: """Deprecated string view of the value. .. deprecated:: 7.1.1 Use :attr:`bytes` for the raw binary value. ``obj`` decodes :attr:`bytes` as text and is lossy for non-UTF-8 data. It will be removed in icalendar 8. """ return to_unicode(self.bytes) def __eq__(self, other: object) -> bool: """self == other""" return isinstance(other, vBinary) and self.bytes == other.bytes def __hash__(self) -> int: """Hash of the vBinary object.""" return hash(self.bytes)
[docs] @classmethod def examples(cls) -> list[Self]: """Examples of vBinary.""" return [cls("VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZy4")]
from icalendar.param import VALUE
[docs] def to_jcal(self, name: str) -> list: """The jCal representation of this property according to :rfc:`7265`.""" params = self.params.to_jcal() if params.get("encoding") == "BASE64": # BASE64 is the only allowed encoding del params["encoding"] return [ name, params, self.VALUE.lower(), base64.b64encode(self.bytes).decode("ascii"), ]
@property def ical_value(self) -> bytes: """The raw ``bytes`` value of the BINARY property. .. versionchanged:: 7.1.1 Returns the raw stored bytes. Previously the stored value was base64-decoded, which raised :class:`ValueError` for non-base64 input. See ``news/1356.breaking``. """ return self.bytes
[docs] @classmethod def from_jcal(cls, jcal_property: list) -> Self: """Parse jCal from :rfc:`7265` to a vBinary. Parameters: jcal_property: The jCal property to parse. Raises: ~error.JCalParsingError: If the provided jCal is invalid. """ JCalParsingError.validate_property(jcal_property, cls) JCalParsingError.validate_value_type(jcal_property[3], str, cls, 3) return cls( cls.from_ical(jcal_property[3]), params=Parameters.from_jcal_property(jcal_property), )
__all__ = ["vBinary"]