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

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

44 statements  

1"""GEO property values from :rfc:`5545`.""" 

2 

3from typing import Any, ClassVar 

4 

5from icalendar.compatibility import Self 

6from icalendar.error import JCalParsingError 

7from icalendar.parser import Parameters 

8 

9 

10class vGeo: 

11 """Geographic Position 

12 

13 Property Name: 

14 GEO 

15 

16 Purpose: 

17 This property specifies information related to the global 

18 position for the activity specified by a calendar component. 

19 

20 Value Type: 

21 FLOAT. The value MUST be two SEMICOLON-separated FLOAT values. 

22 

23 Property Parameters: 

24 IANA and non-standard property parameters can be specified on 

25 this property. 

26 

27 Conformance: 

28 This property can be specified in "VEVENT" or "VTODO" 

29 calendar components. 

30 

31 Description: 

32 This property value specifies latitude and longitude, 

33 in that order (i.e., "LAT LON" ordering). The longitude 

34 represents the location east or west of the prime meridian as a 

35 positive or negative real number, respectively. The longitude and 

36 latitude values MAY be specified up to six decimal places, which 

37 will allow for accuracy to within one meter of geographical 

38 position. Receiving applications MUST accept values of this 

39 precision and MAY truncate values of greater precision. 

40 

41 Example: 

42 

43 .. code-block:: text 

44 

45 GEO:37.386013;-122.082932 

46 

47 Parse vGeo: 

48 

49 .. code-block:: pycon 

50 

51 >>> from icalendar.prop import vGeo 

52 >>> geo = vGeo.from_ical('37.386013;-122.082932') 

53 >>> geo 

54 (37.386013, -122.082932) 

55 

56 Add a geo location to an event: 

57 

58 .. code-block:: pycon 

59 

60 >>> from icalendar import Event 

61 >>> event = Event() 

62 >>> latitude = 37.386013 

63 >>> longitude = -122.082932 

64 >>> event.add('GEO', (latitude, longitude)) 

65 >>> event['GEO'] 

66 vGeo((37.386013, -122.082932)) 

67 """ 

68 

69 default_value: ClassVar[str] = "FLOAT" 

70 params: Parameters 

71 

72 def __init__( 

73 self, 

74 geo: tuple[float | str | int, float | str | int], 

75 /, 

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

77 ): 

78 """Create a new vGeo from a tuple of (latitude, longitude). 

79 

80 Raises: 

81 ValueError: if geo is not a tuple of (latitude, longitude) 

82 """ 

83 try: 

84 latitude, longitude = (geo[0], geo[1]) 

85 latitude = float(latitude) 

86 longitude = float(longitude) 

87 except Exception as e: 

88 raise ValueError( 

89 "Input must be (float, float) for latitude and longitude" 

90 ) from e 

91 self.latitude = latitude 

92 self.longitude = longitude 

93 self.params = Parameters(params) 

94 

95 def to_ical(self) -> str: 

96 return f"{self.latitude};{self.longitude}" 

97 

98 @staticmethod 

99 def from_ical(ical: str) -> tuple[float, float]: 

100 try: 

101 latitude, longitude = ical.split(";") 

102 return (float(latitude), float(longitude)) 

103 except Exception as e: 

104 raise ValueError(f"Expected 'float;float' , got: {ical}") from e 

105 

106 def __eq__(self, other: object) -> bool: 

107 return isinstance(other, vGeo) and self.to_ical() == other.to_ical() 

108 

109 def __hash__(self) -> int: 

110 """Hash of the vGeo object.""" 

111 return hash((self.latitude, self.longitude)) 

112 

113 def __repr__(self) -> str: 

114 """repr(self)""" 

115 return f"{self.__class__.__name__}(({self.latitude}, {self.longitude}))" 

116 

117 def to_jcal(self, name: str) -> list: 

118 """Convert to jCal object.""" 

119 return [ 

120 name, 

121 self.params.to_jcal(), 

122 self.VALUE.lower(), 

123 [self.latitude, self.longitude], 

124 ] 

125 

126 @classmethod 

127 def examples(cls) -> list[Self]: 

128 """Examples of vGeo.""" 

129 return [cls((37.386013, -122.082932))] 

130 

131 from icalendar.param import VALUE 

132 

133 @classmethod 

134 def from_jcal(cls, jcal_property: list) -> Self: 

135 """Parse jCal from :rfc:`7265`. 

136 

137 Parameters: 

138 jcal_property: The jCal property to parse. 

139 

140 Raises: 

141 ~error.JCalParsingError: If the provided jCal is invalid. 

142 """ 

143 JCalParsingError.validate_property(jcal_property, cls) 

144 return cls( 

145 jcal_property[3], 

146 Parameters.from_jcal_property(jcal_property), 

147 ) 

148 

149 

150__all__ = ["vGeo"]