Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/prop/recur/frequency.py: 69%

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

55 statements  

1"""FREQ value type of RECUR from :rfc:`5545`.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, Any 

6from xml.etree.ElementTree import Element, SubElement 

7 

8from icalendar.caselessdict import CaselessDict 

9from icalendar.error import JCalParsingError, XCalParsingError 

10from icalendar.parser import Parameters 

11from icalendar.parser.xcal.wrapper import from_xcal_wrapper 

12from icalendar.parser_tools import DEFAULT_ENCODING, to_unicode 

13 

14if TYPE_CHECKING: 

15 from icalendar.compatibility import Self 

16 from icalendar.parser.xcal.base import XCalParser 

17 

18 

19class vFrequency(str): 

20 """A simple class that catches illegal values.""" 

21 

22 params: Parameters 

23 __slots__ = ("params",) 

24 

25 frequencies = CaselessDict( 

26 { 

27 "SECONDLY": "SECONDLY", 

28 "MINUTELY": "MINUTELY", 

29 "HOURLY": "HOURLY", 

30 "DAILY": "DAILY", 

31 "WEEKLY": "WEEKLY", 

32 "MONTHLY": "MONTHLY", 

33 "YEARLY": "YEARLY", 

34 } 

35 ) 

36 

37 def __new__( 

38 cls, 

39 value, 

40 encoding=DEFAULT_ENCODING, 

41 /, 

42 params: dict[str, Any] | None = None, 

43 ): 

44 value = to_unicode(value, encoding=encoding) 

45 self = super().__new__(cls, value) 

46 if self not in vFrequency.frequencies: 

47 raise ValueError(f"Expected frequency, got: {self}") 

48 self.params = Parameters(params) 

49 return self 

50 

51 def to_ical(self): 

52 return self.encode(DEFAULT_ENCODING).upper() 

53 

54 @classmethod 

55 def from_ical(cls, ical): 

56 try: 

57 return cls(ical.upper()) 

58 except Exception as e: 

59 raise ValueError(f"Expected frequency, got: {ical}") from e 

60 

61 @classmethod 

62 def parse_jcal_value(cls, value: Any) -> Self: 

63 """Parse a jCal value for vFrequency. 

64 

65 Raises: 

66 ~error.JCalParsingError: If the value is not a valid frequency. 

67 """ 

68 JCalParsingError.validate_value_type(value, str, cls) 

69 try: 

70 return cls(value) 

71 except ValueError as e: 

72 raise JCalParsingError( 

73 "The value must be a valid frequency.", cls, value=value 

74 ) from e 

75 

76 @property 

77 def ical_value(self) -> str: 

78 """Returns the frequency value as a string, for example, ``WEEKLY`` or ``DAILY``. 

79 

80 See Also: 

81 

82 :rfc:`5545#section-3.3.10` for the ``FREQ`` rule grammar. 

83 """ 

84 return str(self) 

85 

86 @classmethod 

87 @from_xcal_wrapper 

88 def from_xcal(cls, parser: XCalParser, params: Parameters) -> Self: 

89 """Parse xCal from :rfc:`6321`. 

90 

91 Parameters: 

92 xml: The XML to parse or a parser. 

93 

94 Raises: 

95 ~error.XCalParsingError: If the provided xCal is invalid. 

96 """ 

97 child = parser.parse_tag() 

98 text = child.get_xsd_token() 

99 try: 

100 return cls(text, params=params) 

101 except ValueError as e: 

102 raise XCalParsingError( 

103 "Expected frequency https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.10", 

104 text, 

105 child, 

106 ) from e 

107 

108 def to_xcal(self, element: Element) -> None: 

109 """Add the xCal representation of this property according to :rfc:`6321`.""" 

110 self.params.to_xcal(element) 

111 frequency_element = SubElement(element, "freq") 

112 frequency_element.text = str(self) 

113 

114 

115__all__ = ["vFrequency"]