Fix PublisherCoordinatorReport generation. (#54)

* Fix PublisherCoordinatorReport generation.

Without this patch we are given *either* the failed or the successful
publication reports. We actually need both, this patch implements the
merge.

* Reformat

Co-authored-by: Giacomo Leidi <goodoldpaul@autistici.org>
This commit is contained in:
tinoilcotechino 2021-08-28 13:17:39 +02:00 committed by GitHub
parent 2197e07213
commit 489e3d66ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 86 additions and 27 deletions

View File

@ -51,7 +51,11 @@ def inspect(ctx, begin, end):
@pass_obj
def all(obj, settings_file):
safe_execution(
functools.partial(inspect_events, frm=obj["begin"], to=obj["end"],),
functools.partial(
inspect_events,
frm=obj["begin"],
to=obj["end"],
),
settings_file,
)

View File

@ -45,7 +45,8 @@ async def main():
if event:
waiting_publications = await publications_with_status(
status=PublicationStatus.WAITING, event_mobilizon_id=event.mobilizon_id,
status=PublicationStatus.WAITING,
event_mobilizon_id=event.mobilizon_id,
)
logger.debug(f"Event to publish found: {event.name}")
report = PublisherCoordinator(event, waiting_publications).run()

View File

@ -64,7 +64,11 @@ def build_and_validate_settings(settings_files: List[str] = None):
base_validators = [
# strategy to decide events to publish
Validator(
"publishing.window.begin", must_exist=True, is_type_of=int, gte=0, lte=24,
"publishing.window.begin",
must_exist=True,
is_type_of=int,
gte=0,
lte=24,
),
Validator(
"publishing.window.end", must_exist=True, is_type_of=int, gte=0, lte=24

View File

@ -93,7 +93,8 @@ STRATEGY_NAME_TO_STRATEGY_CLASS = {"next_event": SelectNextEventStrategy}
def select_event_to_publish(
published_events: List[MobilizonEvent], unpublished_events: List[MobilizonEvent],
published_events: List[MobilizonEvent],
unpublished_events: List[MobilizonEvent],
):
strategy = STRATEGY_NAME_TO_STRATEGY_CLASS[

View File

@ -62,7 +62,7 @@ class PublisherCoordinator(BuildPublisherMixin):
return self._post()
def _make_successful_report(self):
def _make_successful_report(self, failed_ids):
return {
publication_id: PublicationReport(
status=PublicationStatus.COMPLETED,
@ -70,6 +70,7 @@ class PublisherCoordinator(BuildPublisherMixin):
publication_id=publication_id,
)
for publication_id in self.publishers_by_publication_id
if publication_id not in failed_ids
}
def _post(self):
@ -84,7 +85,9 @@ class PublisherCoordinator(BuildPublisherMixin):
publication_id=publication_id,
)
reports = failed_publishers_reports or self._make_successful_report()
reports = failed_publishers_reports | self._make_successful_report(
failed_publishers_reports.keys()
)
return PublisherCoordinatorReport(
publishers=self.publishers_by_publication_id, reports=reports
)

View File

@ -54,7 +54,8 @@ class TelegramPublisher(AbstractPublisher):
err.append("username")
if err:
self._log_error(
", ".join(err) + " is/are missing", raise_error=InvalidCredentials,
", ".join(err) + " is/are missing",
raise_error=InvalidCredentials,
)
res = requests.get(f"https://api.telegram.org/bot{token}/getMe")
@ -62,7 +63,8 @@ class TelegramPublisher(AbstractPublisher):
if not username == data.get("result", {}).get("username"):
self._log_error(
"Found a different bot than the expected one", raise_error=InvalidBot,
"Found a different bot than the expected one",
raise_error=InvalidBot,
)
def validate_event(self) -> None:
@ -75,7 +77,8 @@ class TelegramPublisher(AbstractPublisher):
res.raise_for_status()
except requests.exceptions.HTTPError as e:
self._log_error(
f"Server returned invalid data: {str(e)}", raise_error=InvalidResponse,
f"Server returned invalid data: {str(e)}",
raise_error=InvalidResponse,
)
try:
@ -88,7 +91,8 @@ class TelegramPublisher(AbstractPublisher):
if not data.get("ok"):
self._log_error(
f"Invalid request (response: {data})", raise_error=InvalidResponse,
f"Invalid request (response: {data})",
raise_error=InvalidResponse,
)
return data

View File

@ -94,7 +94,8 @@ async def events_with_status(
async def get_all_events(
from_date: Optional[Arrow] = None, to_date: Optional[Arrow] = None,
from_date: Optional[Arrow] = None,
to_date: Optional[Arrow] = None,
) -> Iterable[MobilizonEvent]:
return map(
@ -153,7 +154,9 @@ async def create_publisher(name: str, account_ref: Optional[str] = None) -> None
@atomic(CONNECTION_NAME)
async def update_publishers(names: Iterable[str],) -> None:
async def update_publishers(
names: Iterable[str],
) -> None:
names = set(names)
known_publisher_names = set(p.name for p in await get_publishers())
for name in names.difference(known_publisher_names):
@ -168,7 +171,9 @@ async def save_publication(
publisher = await get_publishers(publisher_name)
await Publication.create(
status=status, event_id=event_model.id, publisher_id=publisher.id,
status=status,
event_id=event_model.id,
publisher_id=publisher.id,
)

View File

@ -123,7 +123,9 @@ def event_model_generator():
@pytest.fixture()
def publisher_model_generator():
def _publisher_model_generator(idx=1,):
def _publisher_model_generator(
idx=1,
):
return Publisher(name=f"publisher_{idx}", account_ref=f"account_ref_{idx}")
return _publisher_model_generator

View File

@ -109,7 +109,9 @@ def test_window_simple_event_found(
@pytest.mark.parametrize("current_hour", [15])
@pytest.mark.parametrize("strategy_name", ["next_event"])
def test_window_simple_no_published_events(
event_generator, set_strategy, mock_arrow_now,
event_generator,
set_strategy,
mock_arrow_now,
):
"Testing that if no event is published, the function takes the first available unpublished event"
unpublished_events = [
@ -130,7 +132,9 @@ def test_window_simple_no_published_events(
@pytest.mark.parametrize("current_hour", [15])
@pytest.mark.parametrize("strategy_name", ["next_event"])
def test_window_simple_event_too_recent(
event_generator, set_strategy, mock_arrow_now,
event_generator,
set_strategy,
mock_arrow_now,
):
"Testing that if an event has been published too recently, no event is selected for publication"
unpublished_events = [

View File

@ -15,7 +15,10 @@ def mock_mobilizon_success_answer(mobilizon_answer, mobilizon_url):
with responses.RequestsMock() as rsps:
rsps.add(
responses.POST, mobilizon_url, json=mobilizon_answer, status=200,
responses.POST,
mobilizon_url,
json=mobilizon_answer,
status=200,
)
yield
@ -26,6 +29,8 @@ def mock_mobilizon_failure_answer(mobilizon_url):
with responses.RequestsMock() as rsps:
rsps.add(
responses.POST, mobilizon_url, status=500,
responses.POST,
mobilizon_url,
status=500,
)
yield

View File

@ -35,7 +35,9 @@ def test_publication_report_successful(statuses, successful):
@pytest.fixture
@pytest.mark.asyncio
async def mock_publication(test_event: MobilizonEvent,):
async def mock_publication(
test_event: MobilizonEvent,
):
event = test_event.to_model()
await event.save()
publisher = Publisher(name="telegram")

View File

@ -5,7 +5,12 @@ from mobilizon_reshare.models.publication import Publication
from mobilizon_reshare.models.publication import PublicationStatus
today = datetime(
year=2021, month=6, day=6, hour=5, minute=0, tzinfo=timezone(timedelta(hours=2)),
year=2021,
month=6,
day=6,
hour=5,
minute=0,
tzinfo=timezone(timedelta(hours=2)),
)

View File

@ -119,7 +119,9 @@ async def test_get_unpublished_events(specification, expected_result, generate_m
],
)
async def test_create_unpublished_events(
expected_result, generate_models, event_generator,
expected_result,
generate_models,
event_generator,
):
await generate_models(complete_specification)
event_3 = event_generator(begin_date=arrow.get(today + timedelta(days=6)))
@ -130,7 +132,9 @@ async def test_create_unpublished_events(
events_from_internet = [MobilizonEvent.from_model(models[0]), event_3, event_4]
await create_unpublished_events(unpublished_mobilizon_events=events_from_internet,)
await create_unpublished_events(
unpublished_mobilizon_events=events_from_internet,
)
unpublished_events = list(await get_unpublished_events())
assert len(unpublished_events) == 4
@ -169,7 +173,9 @@ async def test_get_mobilizon_event_publications(generate_models):
[[None, {"telegram", "twitter", "mastodon"}], ["telegram", {"telegram"}]],
)
async def test_get_publishers(
name, expected_result, generate_models,
name,
expected_result,
generate_models,
):
await generate_models(complete_specification)
result = await get_publishers(name)
@ -232,7 +238,12 @@ async def test_get_publishers(
],
)
async def test_publications_with_status(
status, mobilizon_id, from_date, to_date, expected_result, generate_models,
status,
mobilizon_id,
from_date,
to_date,
expected_result,
generate_models,
):
await generate_models(complete_specification)
publications = await publications_with_status(

View File

@ -48,7 +48,10 @@ two_publishers_specification = {"publisher": ["telegram", "twitter"]}
],
)
async def test_update_publishers(
specification, names, expected_result, generate_models,
specification,
names,
expected_result,
generate_models,
):
await generate_models(specification)
await update_publishers(names)
@ -107,12 +110,17 @@ async def test_update_publishers(
],
)
async def test_save_publication_report(
specification, report, event, expected_result, generate_models,
specification,
report,
event,
expected_result,
generate_models,
):
await generate_models(specification)
publications = await publications_with_status(
status=PublicationStatus.WAITING, event_mobilizon_id=event.mobilizon_id,
status=PublicationStatus.WAITING,
event_mobilizon_id=event.mobilizon_id,
)
await save_publication_report(report, publications)
publication_ids = set(report.reports.keys())