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
« prev ^ index » next coverage.py v7.10.7, created at 2025-11-02 05:49 +0000
1"""Calendar service."""
3from calendar import monthrange
4from datetime import datetime
6from tzlocal import get_localzone
9class CalendarService:
10 """
11 The 'Calendar' iCloud service, connects to iCloud and returns events.
12 """
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"
23 self.response = {}
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]
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()
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")
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"]