Skip to content

Commit 3a759e8

Browse files
authored
Merge pull request #601 from davidhozic/develop
Fixed period bugs
2 parents b4845a8 + bfbb100 commit 3a759e8

File tree

2 files changed

+27
-31
lines changed

2 files changed

+27
-31
lines changed

src/daf/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import warnings
2323

2424

25-
VERSION = "4.1.0"
25+
VERSION = "4.1.0rc1"
2626

2727

2828
if sys.version_info.minor == 12 and sys.version_info.major == 3:

src/daf/message/messageperiod.py

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def adjust(self, minimum: timedelta) -> None:
6363
class DurationPeriod(BaseMessagePeriod):
6464
"""
6565
Base for duration-like message periods.
66-
"""
66+
"""
6767
@abstractmethod
6868
def _get_period(self) -> timedelta:
6969
"Get's the calculated relative period (offset) from previous scheduled time."
@@ -146,14 +146,14 @@ def __init__(
146146
self.maximum = maximum
147147
super().__init__(next_send_time)
148148

149-
149+
150150
def _get_period(self):
151151
return timedelta(seconds=randrange(self.minimum.total_seconds(), self.maximum.total_seconds()))
152152

153153
def adjust(self, minimum: timedelta) -> None:
154154
if self.minimum >= minimum:
155155
return
156-
156+
157157
self.maximum = minimum + (self.maximum - self.minimum) # Preserve the period band's width
158158
self.minimum = minimum
159159

@@ -194,7 +194,7 @@ def __init__(
194194
) -> None:
195195
if not days:
196196
raise ValueError(f"'days' parameter must be a list of day literals {DaysOfWeekPeriod.WEEK_DAYS}.")
197-
197+
198198
if time.tzinfo is None:
199199
time = time.replace(tzinfo=datetime.now().astimezone().tzinfo)
200200

@@ -243,7 +243,7 @@ def calculate(self):
243243
def adjust(self, minimum: timedelta) -> None:
244244
# The minium between sends will always be 24 hours.
245245
# Slow-mode minimum is maximum 6 hours, thus this is not needed.
246-
raise NotImplementedError("Setting minimal period would break the definition of class.")
246+
pass
247247

248248

249249
@doc_category("Message period")
@@ -295,7 +295,7 @@ class NamedDayOfYearPeriod(EveryXPeriod):
295295
Use ``datetime`` to specify the exact date and time at which the message should start being sent.
296296
Use ``timedelta`` to specify how soon (after creation of the object) the message
297297
should start being sent.
298-
298+
299299
Example
300300
----------
301301
.. code-block:: python
@@ -332,7 +332,6 @@ def calculate(self) -> datetime:
332332
now = max(datetime.now().astimezone(), self.next_send_time)
333333
self_time = self.time
334334
next = now.replace(
335-
day=1,
336335
month=self.month,
337336
hour=self_time.hour,
338337
minute=self_time.minute,
@@ -341,23 +340,18 @@ def calculate(self) -> datetime:
341340
)
342341

343342
while True:
344-
isoday = next.isoweekday()
345-
if isoday > self.isoday:
346-
next = next.replace(day=1 + 7 + self.isoday - isoday)
347-
else:
348-
next = next.replace(day=1 + self.isoday - isoday)
349-
350-
next += timedelta(days=7 * (self.week - 1))
351-
343+
next += timedelta(self.isoday - next.isoweekday()) # Move to the named day (e.g., Monday)
344+
next += timedelta(days=7 * (self.week - next.day // 7 - 1)) # Move to the specified weekday (e.g., 2nd (Monday))
352345
if next >= now:
353346
break
354347

355348
next = next.replace(year=next.year + 1)
356349

350+
self.next_send_time = next
357351
return next
358352

359353
def adjust(self, minimum: timedelta) -> None:
360-
raise NotImplementedError("Setting minimal period would break the definition of class.")
354+
pass # Slow-mode can't be one year long
361355

362356

363357
@doc_category("Message period")
@@ -382,7 +376,7 @@ class NamedDayOfMonthPeriod(EveryXPeriod):
382376
Use ``datetime`` to specify the exact date and time at which the message should start being sent.
383377
Use ``timedelta`` to specify how soon (after creation of the object) the message
384378
should start being sent.
385-
379+
386380
Example
387381
----------
388382
.. code-block:: python
@@ -401,39 +395,41 @@ def __init__(
401395
self,
402396
time: time,
403397
day: NamedDayOfMonthPeriod.DAYS,
404-
week: int,
398+
week: Literal[1, 2, 3, 4, 5],
405399
next_send_time: Union[datetime, timedelta] = None
406400
) -> None:
407401
self.time = time
408402
self.day = day
409403
self.week = week
410404
self.isoday = NamedDayOfMonthPeriod._DAYS_ARGS.index(day) + 1
411405
super().__init__(next_send_time)
412-
406+
413407
def calculate(self) -> datetime:
414408
now = max(datetime.now().astimezone(), self.next_send_time)
415409
self_time = self.time
416410
next = now.replace(
417-
day=1,
418411
hour=self_time.hour,
419412
minute=self_time.minute,
420413
second=self_time.second,
421414
microsecond=self_time.microsecond
422415
)
423416

424417
while True:
425-
isoday = next.isoweekday()
426-
if isoday > self.isoday:
427-
next = next.replace(day=1 + 7 + self.isoday - isoday)
428-
else:
429-
next = next.replace(day=1 + self.isoday - isoday)
430-
431-
next += timedelta(days=7 * (self.week - 1))
432-
418+
next += timedelta(self.isoday - next.isoweekday()) # Move to the named day (e.g., Monday)
419+
next += timedelta(days=7 * (self.week - next.day // 7 - 1)) # Move to the specified weekday (e.g., 2nd (Monday))
433420
if next >= now:
434421
break
435422

436-
next = next.replace(month=next.month + 1)
423+
next_month = next.month + 1
424+
next_year = next.year
425+
if next_month > 12:
426+
next_year += 1
427+
next_month = 1
428+
429+
next = next.replace(year=next_year, month=next_month)
430+
431+
self.next_send_time = next
432+
return next
437433

438434
def adjust(self, minimum: timedelta) -> None:
439-
raise NotImplementedError("Setting minimal period would break the definition of class.")
435+
pass # Slow-mode can't be one month long

0 commit comments

Comments
 (0)