Coverage for icloudpy/services/calendar.py: 39%

44 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-11-02 05:49 +0000

1"""Calendar service.""" 

2 

3from calendar import monthrange 

4from datetime import datetime 

5 

6from tzlocal import get_localzone 

7 

8 

9class CalendarService: 

10 """ 

11 The 'Calendar' iCloud service, connects to iCloud and returns events. 

12 """ 

13 

14 def __init__(self, service_root, session, params): 

15 self.session = session 

16 self.params = params 

17 self._service_root = service_root 

18 self._calendar_endpoint = f"{self._service_root}/ca" 

19 self._calendar_refresh_url = f"{self._calendar_endpoint}/events" 

20 self._calendar_event_detail_url = f"{self._calendar_endpoint}/eventdetail" 

21 self._calendars = f"{self._calendar_endpoint}/startup" 

22 

23 self.response = {} 

24 

25 def get_event_detail(self, pguid, guid): 

26 """ 

27 Fetches a single event's details by specifying a pguid 

28 (a calendar) and a guid (an event's ID). 

29 """ 

30 params = dict(self.params) 

31 params.update( 

32 { 

33 "lang": "en-us", 

34 "usertz": str(get_localzone()), 

35 "dsid": self.session.service.data["dsInfo"]["dsid"], 

36 }, 

37 ) 

38 url = f"{self._calendar_event_detail_url}/{pguid}/{guid}" 

39 req = self.session.get(url, params=params) 

40 self.response = req.json() 

41 return self.response["Event"][0] 

42 

43 def refresh_client(self, from_dt=None, to_dt=None): 

44 """ 

45 Refreshes the CalendarService endpoint, ensuring that the 

46 event data is up-to-date. If no 'from_dt' or 'to_dt' datetimes 

47 have been given, the range becomes this month. 

48 """ 

49 today = datetime.today() 

50 _, last_day = monthrange(today.year, today.month) 

51 if not from_dt: 

52 from_dt = datetime(today.year, today.month, 1) 

53 if not to_dt: 

54 to_dt = datetime(today.year, today.month, last_day) 

55 params = dict(self.params) 

56 params.update( 

57 { 

58 "lang": "en-us", 

59 "usertz": str(get_localzone()), 

60 "startDate": from_dt.strftime("%Y-%m-%d"), 

61 "endDate": to_dt.strftime("%Y-%m-%d"), 

62 "dsid": self.session.service.data["dsInfo"]["dsid"], 

63 }, 

64 ) 

65 req = self.session.get(self._calendar_refresh_url, params=params) 

66 self.response = req.json() 

67 

68 def events(self, from_dt=None, to_dt=None): 

69 """ 

70 Retrieves events for a given date range, by default, this month. 

71 """ 

72 self.refresh_client(from_dt, to_dt) 

73 return self.response.get("Event") 

74 

75 def calendars(self): 

76 """ 

77 Retrieves calendars of this month. 

78 """ 

79 today = datetime.today() 

80 _, last_day = monthrange(today.year, today.month) 

81 from_dt = datetime(today.year, today.month, 1) 

82 to_dt = datetime(today.year, today.month, last_day) 

83 params = dict(self.params) 

84 params.update( 

85 { 

86 "lang": "en-us", 

87 "usertz": str(get_localzone()), 

88 "startDate": from_dt.strftime("%Y-%m-%d"), 

89 "endDate": to_dt.strftime("%Y-%m-%d"), 

90 "dsid": self.session.service.data["dsInfo"]["dsid"], 

91 }, 

92 ) 

93 req = self.session.get(self._calendars, params=params) 

94 self.response = req.json() 

95 return self.response["Collection"]