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 @pass_obj
def all(obj, settings_file): def all(obj, settings_file):
safe_execution( safe_execution(
functools.partial(inspect_events, frm=obj["begin"], to=obj["end"],), functools.partial(
inspect_events,
frm=obj["begin"],
to=obj["end"],
),
settings_file, settings_file,
) )

View File

@ -45,7 +45,8 @@ async def main():
if event: if event:
waiting_publications = await publications_with_status( 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}") logger.debug(f"Event to publish found: {event.name}")
report = PublisherCoordinator(event, waiting_publications).run() report = PublisherCoordinator(event, waiting_publications).run()

View File

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

View File

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

View File

@ -54,7 +54,8 @@ class TelegramPublisher(AbstractPublisher):
err.append("username") err.append("username")
if err: if err:
self._log_error( 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") 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"): if not username == data.get("result", {}).get("username"):
self._log_error( 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: def validate_event(self) -> None:
@ -75,7 +77,8 @@ class TelegramPublisher(AbstractPublisher):
res.raise_for_status() res.raise_for_status()
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
self._log_error( self._log_error(
f"Server returned invalid data: {str(e)}", raise_error=InvalidResponse, f"Server returned invalid data: {str(e)}",
raise_error=InvalidResponse,
) )
try: try:
@ -88,7 +91,8 @@ class TelegramPublisher(AbstractPublisher):
if not data.get("ok"): if not data.get("ok"):
self._log_error( self._log_error(
f"Invalid request (response: {data})", raise_error=InvalidResponse, f"Invalid request (response: {data})",
raise_error=InvalidResponse,
) )
return data return data

View File

@ -94,7 +94,8 @@ async def events_with_status(
async def get_all_events( 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]: ) -> Iterable[MobilizonEvent]:
return map( return map(
@ -153,7 +154,9 @@ async def create_publisher(name: str, account_ref: Optional[str] = None) -> None
@atomic(CONNECTION_NAME) @atomic(CONNECTION_NAME)
async def update_publishers(names: Iterable[str],) -> None: async def update_publishers(
names: Iterable[str],
) -> None:
names = set(names) names = set(names)
known_publisher_names = set(p.name for p in await get_publishers()) known_publisher_names = set(p.name for p in await get_publishers())
for name in names.difference(known_publisher_names): for name in names.difference(known_publisher_names):
@ -168,7 +171,9 @@ async def save_publication(
publisher = await get_publishers(publisher_name) publisher = await get_publishers(publisher_name)
await Publication.create( 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() @pytest.fixture()
def publisher_model_generator(): 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(name=f"publisher_{idx}", account_ref=f"account_ref_{idx}")
return _publisher_model_generator 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("current_hour", [15])
@pytest.mark.parametrize("strategy_name", ["next_event"]) @pytest.mark.parametrize("strategy_name", ["next_event"])
def test_window_simple_no_published_events( 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" "Testing that if no event is published, the function takes the first available unpublished event"
unpublished_events = [ unpublished_events = [
@ -130,7 +132,9 @@ def test_window_simple_no_published_events(
@pytest.mark.parametrize("current_hour", [15]) @pytest.mark.parametrize("current_hour", [15])
@pytest.mark.parametrize("strategy_name", ["next_event"]) @pytest.mark.parametrize("strategy_name", ["next_event"])
def test_window_simple_event_too_recent( 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" "Testing that if an event has been published too recently, no event is selected for publication"
unpublished_events = [ unpublished_events = [

View File

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

View File

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

View File

@ -5,7 +5,12 @@ from mobilizon_reshare.models.publication import Publication
from mobilizon_reshare.models.publication import PublicationStatus from mobilizon_reshare.models.publication import PublicationStatus
today = datetime( 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( async def test_create_unpublished_events(
expected_result, generate_models, event_generator, expected_result,
generate_models,
event_generator,
): ):
await generate_models(complete_specification) await generate_models(complete_specification)
event_3 = event_generator(begin_date=arrow.get(today + timedelta(days=6))) 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] 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()) unpublished_events = list(await get_unpublished_events())
assert len(unpublished_events) == 4 assert len(unpublished_events) == 4
@ -169,7 +173,9 @@ async def test_get_mobilizon_event_publications(generate_models):
[[None, {"telegram", "twitter", "mastodon"}], ["telegram", {"telegram"}]], [[None, {"telegram", "twitter", "mastodon"}], ["telegram", {"telegram"}]],
) )
async def test_get_publishers( async def test_get_publishers(
name, expected_result, generate_models, name,
expected_result,
generate_models,
): ):
await generate_models(complete_specification) await generate_models(complete_specification)
result = await get_publishers(name) result = await get_publishers(name)
@ -232,7 +238,12 @@ async def test_get_publishers(
], ],
) )
async def test_publications_with_status( 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) await generate_models(complete_specification)
publications = await publications_with_status( publications = await publications_with_status(

View File

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