Added publisher coordinator (#33)
* Added publisher coordinator, emptied __init__ file * Lesser refactoring to coordinator methods * PublisherCoordinatorResult: status turned from str to PublicationStatus * Better usage of reporting classes to manage results * Lesser fix to Telegram _validate_response method
This commit is contained in:
parent
d89659735d
commit
52e34f94bd
|
@ -1,45 +0,0 @@
|
|||
from typing import Iterable
|
||||
|
||||
from .abstract import AbstractPublisher
|
||||
from .exceptions import PublisherError
|
||||
|
||||
|
||||
def run(publishers: Iterable[AbstractPublisher]) -> dict:
|
||||
invalid_credentials, invalid_event, invalid_msg = [], [], []
|
||||
for p in publishers:
|
||||
if not p.are_credentials_valid():
|
||||
invalid_credentials.append(p)
|
||||
if not p.is_event_valid():
|
||||
invalid_event.append(p)
|
||||
if not p.is_message_valid():
|
||||
invalid_msg.append(p)
|
||||
if invalid_credentials or invalid_event or invalid_msg:
|
||||
# TODO: consider to use exceptions or data class if necessary
|
||||
return {
|
||||
"status": "fail",
|
||||
"description": "Validation failed for at least 1 publisher",
|
||||
"invalid_credentials": invalid_credentials,
|
||||
"invalid_event": invalid_event,
|
||||
"invalid_msg": invalid_msg,
|
||||
}
|
||||
|
||||
failed_publishers, successful_publishers = [], []
|
||||
for p in publishers:
|
||||
try:
|
||||
p.post()
|
||||
except PublisherError:
|
||||
failed_publishers.append(p)
|
||||
else:
|
||||
successful_publishers.append(p)
|
||||
|
||||
if failed_publishers:
|
||||
return {
|
||||
"status": "fail",
|
||||
"description": "Posting failed for at least 1 publisher",
|
||||
"failed_publishers": failed_publishers,
|
||||
"successful_publishers": successful_publishers,
|
||||
}
|
||||
return {
|
||||
"status": "success",
|
||||
"description": "https://www.youtube.com/watch?v=2lHgmC6PBBE",
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
from dataclasses import dataclass, field
|
||||
|
||||
from mobilizon_bots.config.config import settings
|
||||
from mobilizon_bots.config.publishers import get_active_publishers
|
||||
from mobilizon_bots.event.event import MobilizonEvent, PublicationStatus
|
||||
from .exceptions import PublisherError
|
||||
from .abstract import AbstractPublisher
|
||||
from .telegram import TelegramPublisher
|
||||
|
||||
KEY2CLS = {"telegram": TelegramPublisher}
|
||||
|
||||
|
||||
@dataclass
|
||||
class PublisherReport:
|
||||
status: PublicationStatus
|
||||
reason: str
|
||||
publisher: AbstractPublisher
|
||||
event: MobilizonEvent
|
||||
|
||||
|
||||
@dataclass
|
||||
class PublisherCoordinatorReport:
|
||||
reports: list = field(default_factory=[])
|
||||
|
||||
@property
|
||||
def successful(self):
|
||||
return all(r.status == PublicationStatus.COMPLETED for r in self.reports)
|
||||
|
||||
|
||||
class PublisherCoordinator:
|
||||
def __init__(self, event: MobilizonEvent):
|
||||
self.publishers = tuple(
|
||||
KEY2CLS[pn](event) for pn in get_active_publishers(settings)
|
||||
)
|
||||
|
||||
def run(self) -> PublisherCoordinatorReport:
|
||||
invalid_credentials, invalid_event, invalid_msg = self._validate()
|
||||
if invalid_credentials or invalid_event or invalid_msg:
|
||||
return PublisherCoordinatorReport(
|
||||
reports=invalid_credentials + invalid_event + invalid_msg
|
||||
)
|
||||
|
||||
failed_publishers = self._post()
|
||||
if failed_publishers:
|
||||
return PublisherCoordinatorReport(reports=failed_publishers)
|
||||
|
||||
return PublisherCoordinatorReport(
|
||||
reports=[
|
||||
PublisherReport(
|
||||
status=PublicationStatus.COMPLETED,
|
||||
reason="",
|
||||
publisher=p,
|
||||
event=p.event,
|
||||
)
|
||||
for p in self.publishers
|
||||
],
|
||||
)
|
||||
|
||||
def _post(self):
|
||||
failed_publishers = []
|
||||
for p in self.publishers:
|
||||
try:
|
||||
p.post()
|
||||
except PublisherError as e:
|
||||
failed_publishers.append(
|
||||
PublisherReport(
|
||||
status=PublicationStatus.FAILED,
|
||||
reason=repr(e),
|
||||
publisher=p,
|
||||
event=p.event,
|
||||
)
|
||||
)
|
||||
return failed_publishers
|
||||
|
||||
def _validate(self):
|
||||
invalid_credentials, invalid_event, invalid_msg = [], [], []
|
||||
for p in self.publishers:
|
||||
if not p.are_credentials_valid():
|
||||
invalid_credentials.append(
|
||||
PublisherReport(
|
||||
status=PublicationStatus.FAILED,
|
||||
reason="Invalid credentials",
|
||||
publisher=p,
|
||||
event=p.event,
|
||||
)
|
||||
)
|
||||
if not p.is_event_valid():
|
||||
invalid_event.append(
|
||||
PublisherReport(
|
||||
status=PublicationStatus.FAILED,
|
||||
reason="Invalid event",
|
||||
publisher=p,
|
||||
event=p.event,
|
||||
)
|
||||
)
|
||||
if not p.is_message_valid():
|
||||
invalid_msg.append(
|
||||
PublisherReport(
|
||||
status=PublicationStatus.FAILED,
|
||||
reason="Invalid message",
|
||||
publisher=p,
|
||||
event=p.event,
|
||||
)
|
||||
)
|
||||
return invalid_credentials, invalid_event, invalid_msg
|
|
@ -57,7 +57,13 @@ class TelegramPublisher(AbstractPublisher):
|
|||
self._log_error("No text was found", raise_error=InvalidEvent)
|
||||
|
||||
def _validate_response(self, res):
|
||||
try:
|
||||
res.raise_for_status()
|
||||
except requests.exceptions.HTTPError as e:
|
||||
self._log_error(
|
||||
f"Server returned invalid data: {str(e)}",
|
||||
raise_error=InvalidResponse,
|
||||
)
|
||||
|
||||
try:
|
||||
data = res.json()
|
||||
|
|
Loading…
Reference in New Issue