2021-05-05 14:29:13 +02:00
|
|
|
from abc import ABC, abstractmethod
|
2021-05-04 22:58:00 +02:00
|
|
|
from typing import List, Optional
|
2021-05-30 21:47:36 +02:00
|
|
|
import arrow
|
2021-05-04 22:58:00 +02:00
|
|
|
|
2021-07-07 11:19:37 +02:00
|
|
|
from mobilizon_bots.config.config import settings
|
2021-05-04 22:58:00 +02:00
|
|
|
from mobilizon_bots.event.event import MobilizonEvent
|
|
|
|
|
|
|
|
|
|
|
|
class EventSelectionStrategy(ABC):
|
|
|
|
def select(
|
|
|
|
self,
|
|
|
|
published_events: List[MobilizonEvent],
|
|
|
|
unpublished_events: List[MobilizonEvent],
|
2021-07-07 11:19:37 +02:00
|
|
|
) -> Optional[MobilizonEvent]:
|
|
|
|
|
|
|
|
if not self.is_in_publishing_window():
|
|
|
|
return None
|
|
|
|
return self._select(published_events, unpublished_events)
|
|
|
|
|
|
|
|
def is_in_publishing_window(self) -> bool:
|
|
|
|
window_beginning = settings["publishing"]["window"]["begin"]
|
|
|
|
window_end = settings["publishing"]["window"]["end"]
|
|
|
|
now_hour = arrow.now().datetime.hour
|
|
|
|
if window_beginning <= window_end:
|
|
|
|
return window_beginning <= now_hour < window_end
|
|
|
|
else:
|
|
|
|
return now_hour >= window_beginning or now_hour < window_end
|
|
|
|
|
|
|
|
@abstractmethod
|
|
|
|
def _select(
|
|
|
|
self,
|
|
|
|
published_events: List[MobilizonEvent],
|
|
|
|
unpublished_events: List[MobilizonEvent],
|
2021-05-04 22:58:00 +02:00
|
|
|
) -> Optional[MobilizonEvent]:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
class SelectNextEventStrategy(EventSelectionStrategy):
|
2021-05-30 21:47:36 +02:00
|
|
|
def __init__(self, minimum_break_between_events_in_minutes: int):
|
|
|
|
self.minimum_break_between_events_in_minutes = (
|
|
|
|
minimum_break_between_events_in_minutes
|
|
|
|
)
|
2021-05-04 22:58:00 +02:00
|
|
|
|
2021-07-07 11:19:37 +02:00
|
|
|
def _select(
|
2021-05-04 22:58:00 +02:00
|
|
|
self,
|
|
|
|
published_events: List[MobilizonEvent],
|
|
|
|
unpublished_events: List[MobilizonEvent],
|
2021-07-05 23:07:12 +02:00
|
|
|
publisher_name: str = "telegram",
|
2021-05-04 22:58:00 +02:00
|
|
|
) -> Optional[MobilizonEvent]:
|
|
|
|
|
|
|
|
last_published_event = published_events[-1]
|
|
|
|
first_unpublished_event = unpublished_events[0]
|
2021-05-30 21:47:36 +02:00
|
|
|
now = arrow.now()
|
2021-07-05 23:07:12 +02:00
|
|
|
assert last_published_event.publication_time[publisher_name] < now, (
|
2021-05-05 14:29:13 +02:00
|
|
|
f"Last published event has been published in the future\n"
|
2021-07-05 23:07:12 +02:00
|
|
|
f"{last_published_event.publication_time[publisher_name]}\n"
|
2021-05-30 21:47:36 +02:00
|
|
|
f"{now}"
|
2021-05-05 14:29:13 +02:00
|
|
|
)
|
2021-05-04 22:58:00 +02:00
|
|
|
if (
|
2021-07-05 23:07:12 +02:00
|
|
|
last_published_event.publication_time[publisher_name].shift(
|
2021-05-30 21:47:36 +02:00
|
|
|
minutes=self.minimum_break_between_events_in_minutes
|
|
|
|
)
|
|
|
|
> now
|
2021-05-04 22:58:00 +02:00
|
|
|
):
|
|
|
|
return None
|
|
|
|
|
|
|
|
return first_unpublished_event
|
|
|
|
|
|
|
|
|
|
|
|
class EventSelector:
|
|
|
|
def __init__(
|
|
|
|
self,
|
|
|
|
published_events: List[MobilizonEvent],
|
|
|
|
unpublished_events: List[MobilizonEvent],
|
|
|
|
):
|
|
|
|
self.published_events = published_events.sort(key=lambda x: x.begin_datetime)
|
|
|
|
self.unpublished_events = unpublished_events.sort(
|
|
|
|
key=lambda x: x.begin_datetime
|
|
|
|
)
|
|
|
|
|
|
|
|
def select_event_to_publish(
|
|
|
|
self, strategy: EventSelectionStrategy
|
|
|
|
) -> Optional[MobilizonEvent]:
|
2021-07-07 11:19:37 +02:00
|
|
|
return strategy._select(self.published_events, self.unpublished_events)
|