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:
SlyK182 2021-07-07 11:45:54 +02:00 committed by GitHub
parent d89659735d
commit 52e34f94bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 46 deletions

View File

@ -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",
}

View File

@ -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

View File

@ -57,7 +57,13 @@ class TelegramPublisher(AbstractPublisher):
self._log_error("No text was found", raise_error=InvalidEvent) self._log_error("No text was found", raise_error=InvalidEvent)
def _validate_response(self, res): def _validate_response(self, res):
try:
res.raise_for_status() res.raise_for_status()
except requests.exceptions.HTTPError as e:
self._log_error(
f"Server returned invalid data: {str(e)}",
raise_error=InvalidResponse,
)
try: try:
data = res.json() data = res.json()