Skip to content

Commit 456570c

Browse files
committed
Add rrule prepare() support
This moves some functionality from the high-level interface to the client. Signed-off-by: Mathias L. Baumann <[email protected]>
1 parent 7d351bc commit 456570c

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ dev-mypy = [
8080
"frequenz-client-dispatch[cli,dev-mkdocs,dev-noxfile,dev-pytest]",
8181
"grpc-stubs == 1.53.0.5",
8282
"types-protobuf == 5.28.3.20241030",
83+
"types-python-dateutil == 2.9.0.20241003",
8384
]
8485
dev-noxfile = ["nox == 2024.10.9", "frequenz-repo-config[lib] == 0.10.0"]
8586
dev-pylint = [

src/frequenz/client/dispatch/recurrence.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@ class Frequency(IntEnum):
4242
YEARLY = PBRecurrenceRule.FREQUENCY_YEARLY
4343

4444

45+
_RRULE_FREQ_MAP = {
46+
Frequency.MINUTELY: rrule.MINUTELY,
47+
Frequency.HOURLY: rrule.HOURLY,
48+
Frequency.DAILY: rrule.DAILY,
49+
Frequency.WEEKLY: rrule.WEEKLY,
50+
Frequency.MONTHLY: rrule.MONTHLY,
51+
}
52+
"""To map from our Frequency enum to the dateutil library enum."""
53+
54+
_RRULE_WEEKDAY_MAP = {
55+
Weekday.MONDAY: rrule.MO,
56+
Weekday.TUESDAY: rrule.TU,
57+
Weekday.WEDNESDAY: rrule.WE,
58+
Weekday.THURSDAY: rrule.TH,
59+
Weekday.FRIDAY: rrule.FR,
60+
Weekday.SATURDAY: rrule.SA,
61+
Weekday.SUNDAY: rrule.SU,
62+
}
63+
"""To map from our Weekday enum to the dateutil library enum."""
64+
65+
4566
@dataclass(kw_only=True)
4667
class EndCriteria:
4768
"""Controls when a recurring dispatch should end."""
@@ -164,3 +185,39 @@ def to_protobuf(self) -> PBRecurrenceRule:
164185
pb_rule.bymonths.extend(self.bymonths)
165186

166187
return pb_rule
188+
189+
def prepare(self, start_time: datetime) -> rrule.rrule:
190+
"""Prepare the rrule object.
191+
192+
Args:
193+
start_time: The start time of the dispatch.
194+
195+
Returns:
196+
The rrule object.
197+
198+
Raises:
199+
ValueError: If the interval is 0.
200+
"""
201+
if self.interval == 0:
202+
raise ValueError("Interval must be greater than 0")
203+
204+
count, until = (None, None)
205+
if end := self.end_criteria:
206+
count = end.count
207+
until = end.until
208+
209+
rrule_obj = rrule.rrule(
210+
freq=_RRULE_FREQ_MAP[self.frequency],
211+
dtstart=start_time,
212+
count=count,
213+
until=until,
214+
byminute=self.byminutes or None,
215+
byhour=self.byhours or None,
216+
byweekday=[_RRULE_WEEKDAY_MAP[weekday] for weekday in self.byweekdays]
217+
or None,
218+
bymonthday=self.bymonthdays or None,
219+
bymonth=self.bymonths or None,
220+
interval=self.interval,
221+
)
222+
223+
return rrule_obj

0 commit comments

Comments
 (0)