Skip to content

Commit

Permalink
Merge pull request #601 from davidhozic/develop
Browse files Browse the repository at this point in the history
Fixed period bugs
  • Loading branch information
davidhozic authored Sep 13, 2024
2 parents b4845a8 + bfbb100 commit 3a759e8
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 31 deletions.
2 changes: 1 addition & 1 deletion src/daf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import warnings


VERSION = "4.1.0"
VERSION = "4.1.0rc1"


if sys.version_info.minor == 12 and sys.version_info.major == 3:
Expand Down
56 changes: 26 additions & 30 deletions src/daf/message/messageperiod.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def adjust(self, minimum: timedelta) -> None:
class DurationPeriod(BaseMessagePeriod):
"""
Base for duration-like message periods.
"""
"""
@abstractmethod
def _get_period(self) -> timedelta:
"Get's the calculated relative period (offset) from previous scheduled time."
Expand Down Expand Up @@ -146,14 +146,14 @@ def __init__(
self.maximum = maximum
super().__init__(next_send_time)


def _get_period(self):
return timedelta(seconds=randrange(self.minimum.total_seconds(), self.maximum.total_seconds()))

def adjust(self, minimum: timedelta) -> None:
if self.minimum >= minimum:
return

self.maximum = minimum + (self.maximum - self.minimum) # Preserve the period band's width
self.minimum = minimum

Expand Down Expand Up @@ -194,7 +194,7 @@ def __init__(
) -> None:
if not days:
raise ValueError(f"'days' parameter must be a list of day literals {DaysOfWeekPeriod.WEEK_DAYS}.")

if time.tzinfo is None:
time = time.replace(tzinfo=datetime.now().astimezone().tzinfo)

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


@doc_category("Message period")
Expand Down Expand Up @@ -295,7 +295,7 @@ class NamedDayOfYearPeriod(EveryXPeriod):
Use ``datetime`` to specify the exact date and time at which the message should start being sent.
Use ``timedelta`` to specify how soon (after creation of the object) the message
should start being sent.
Example
----------
.. code-block:: python
Expand Down Expand Up @@ -332,7 +332,6 @@ def calculate(self) -> datetime:
now = max(datetime.now().astimezone(), self.next_send_time)
self_time = self.time
next = now.replace(
day=1,
month=self.month,
hour=self_time.hour,
minute=self_time.minute,
Expand All @@ -341,23 +340,18 @@ def calculate(self) -> datetime:
)

while True:
isoday = next.isoweekday()
if isoday > self.isoday:
next = next.replace(day=1 + 7 + self.isoday - isoday)
else:
next = next.replace(day=1 + self.isoday - isoday)

next += timedelta(days=7 * (self.week - 1))

next += timedelta(self.isoday - next.isoweekday()) # Move to the named day (e.g., Monday)
next += timedelta(days=7 * (self.week - next.day // 7 - 1)) # Move to the specified weekday (e.g., 2nd (Monday))
if next >= now:
break

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

self.next_send_time = next
return next

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


@doc_category("Message period")
Expand All @@ -382,7 +376,7 @@ class NamedDayOfMonthPeriod(EveryXPeriod):
Use ``datetime`` to specify the exact date and time at which the message should start being sent.
Use ``timedelta`` to specify how soon (after creation of the object) the message
should start being sent.
Example
----------
.. code-block:: python
Expand All @@ -401,39 +395,41 @@ def __init__(
self,
time: time,
day: NamedDayOfMonthPeriod.DAYS,
week: int,
week: Literal[1, 2, 3, 4, 5],
next_send_time: Union[datetime, timedelta] = None
) -> None:
self.time = time
self.day = day
self.week = week
self.isoday = NamedDayOfMonthPeriod._DAYS_ARGS.index(day) + 1
super().__init__(next_send_time)

def calculate(self) -> datetime:
now = max(datetime.now().astimezone(), self.next_send_time)
self_time = self.time
next = now.replace(
day=1,
hour=self_time.hour,
minute=self_time.minute,
second=self_time.second,
microsecond=self_time.microsecond
)

while True:
isoday = next.isoweekday()
if isoday > self.isoday:
next = next.replace(day=1 + 7 + self.isoday - isoday)
else:
next = next.replace(day=1 + self.isoday - isoday)

next += timedelta(days=7 * (self.week - 1))

next += timedelta(self.isoday - next.isoweekday()) # Move to the named day (e.g., Monday)
next += timedelta(days=7 * (self.week - next.day // 7 - 1)) # Move to the specified weekday (e.g., 2nd (Monday))
if next >= now:
break

next = next.replace(month=next.month + 1)
next_month = next.month + 1
next_year = next.year
if next_month > 12:
next_year += 1
next_month = 1

next = next.replace(year=next_year, month=next_month)

self.next_send_time = next
return next

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

0 comments on commit 3a759e8

Please sign in to comment.