From bc61ad6123fe4a6c99ad0afa8a10570af522af84 Mon Sep 17 00:00:00 2001 From: Simone Robutti Date: Mon, 25 Oct 2021 13:43:38 +0200 Subject: [PATCH] cli help messages (#85) * added basic recap feature (no error handling) * introduced abstractpublication * extracted base reports * added error report to recap * added test * added docs * implemented publisher and formatter * fixed API for recap * removed redundant config validation * added config sample * added mobilizon link to templates * added link format to telegram * added mobilizon link to recap * fixed config and emoji * refactored commands * added help messages * improved format --- mobilizon_reshare/cli/cli.py | 66 +++++++++++++------ .../{publish_event => commands}/__init__.py | 0 .../format}/__init__.py | 0 .../cli/{ => commands/format}/format.py | 0 .../cli/commands/inspect/__init__.py | 0 .../{ => commands/inspect}/inspect_event.py | 0 .../cli/commands/recap/__init__.py | 0 mobilizon_reshare/cli/commands/recap/main.py | 11 ++++ .../cli/commands/start/__init__.py | 0 mobilizon_reshare/cli/commands/start/main.py | 10 +++ mobilizon_reshare/main/__init__.py | 0 .../publish_recap/main.py => main/recap.py} | 13 ++-- .../publish_event/main.py => main/start.py} | 13 +--- mobilizon_reshare/publishers/coordinator.py | 4 +- 14 files changed, 74 insertions(+), 43 deletions(-) rename mobilizon_reshare/cli/{publish_event => commands}/__init__.py (100%) rename mobilizon_reshare/cli/{publish_recap => commands/format}/__init__.py (100%) rename mobilizon_reshare/cli/{ => commands/format}/format.py (100%) create mode 100644 mobilizon_reshare/cli/commands/inspect/__init__.py rename mobilizon_reshare/cli/{ => commands/inspect}/inspect_event.py (100%) create mode 100644 mobilizon_reshare/cli/commands/recap/__init__.py create mode 100644 mobilizon_reshare/cli/commands/recap/main.py create mode 100644 mobilizon_reshare/cli/commands/start/__init__.py create mode 100644 mobilizon_reshare/cli/commands/start/main.py create mode 100644 mobilizon_reshare/main/__init__.py rename mobilizon_reshare/{cli/publish_recap/main.py => main/recap.py} (89%) rename mobilizon_reshare/{cli/publish_event/main.py => main/start.py} (93%) diff --git a/mobilizon_reshare/cli/cli.py b/mobilizon_reshare/cli/cli.py index 8bb08dd..c79d389 100644 --- a/mobilizon_reshare/cli/cli.py +++ b/mobilizon_reshare/cli/cli.py @@ -1,18 +1,33 @@ import functools +from enum import Enum import click from arrow import Arrow from click import pass_context from mobilizon_reshare.cli import safe_execution -from mobilizon_reshare.cli.format import format_event -from mobilizon_reshare.cli.inspect_event import inspect_events -from mobilizon_reshare.cli.publish_event.main import main as start_main -from mobilizon_reshare.cli.publish_recap.main import main as recap_main +from mobilizon_reshare.cli.commands.format.format import format_event +from mobilizon_reshare.cli.commands.inspect.inspect_event import inspect_events +from mobilizon_reshare.cli.commands.start.main import main as start_main +from mobilizon_reshare.cli.commands.recap.main import main as recap_main +from mobilizon_reshare.config.publishers import publisher_names from mobilizon_reshare.event.event import EventPublicationStatus -settings_file_option = click.option("--settings-file", type=click.Path(exists=True)) +status_name_to_enum = { + "waiting": EventPublicationStatus.WAITING, + "completed": EventPublicationStatus.COMPLETED, + "failed": EventPublicationStatus.FAILED, + "partial": EventPublicationStatus.PARTIAL, + "all": None, +} + +settings_file_option = click.option( + "--settings-file", + type=click.Path(exists=True), + help="The path for the settings file. " + "Overrides the one specified in the environment variables.", +) from_date_option = click.option( "--begin", type=click.DateTime(), @@ -27,50 +42,59 @@ to_date_option = click.option( ) +class InspectTarget(Enum): + ALL = "all" + WAITING = "waiting" + + def __str__(self): + return self.value + + @click.group() def mobilizon_reshare(): pass -@mobilizon_reshare.command() +@mobilizon_reshare.command(help="Synchronize and publish events") @settings_file_option def start(settings_file): safe_execution(start_main, settings_file=settings_file) -@mobilizon_reshare.command() +@mobilizon_reshare.command(help="Publish a recap of already published events") @settings_file_option def recap(settings_file): safe_execution(recap_main, settings_file=settings_file) -@mobilizon_reshare.command() +@mobilizon_reshare.command(help="Print events in the database that are in STATUS") @from_date_option @to_date_option -@click.argument("target", type=str) +@click.argument( + "status", type=click.Choice(list(status_name_to_enum.keys())), +) @settings_file_option @pass_context -def inspect(ctx, target, begin, end, settings_file): +def inspect(ctx, status, begin, end, settings_file): ctx.ensure_object(dict) begin = Arrow.fromdatetime(begin) if begin else None end = Arrow.fromdatetime(end) if end else None - target_to_status = { - "waiting": EventPublicationStatus.WAITING, - "completed": EventPublicationStatus.COMPLETED, - "failed": EventPublicationStatus.FAILED, - "partial": EventPublicationStatus.PARTIAL, - "all": None, - } + safe_execution( - functools.partial(inspect_events, target_to_status[target], frm=begin, to=end,), + functools.partial( + inspect_events, status_name_to_enum[status], frm=begin, to=end, + ), settings_file, ) -@mobilizon_reshare.command() +@mobilizon_reshare.command( + help="Format and print event with mobilizon id EVENT-ID using the publisher's format named" + "PUBLISHER" +) @settings_file_option -@click.argument("event-id", type=str) -@click.argument("publisher", type=str) +@click.argument("event-id", type=click.UUID) +@click.argument("publisher", type=click.Choice(publisher_names)) def format(settings_file, event_id, publisher): safe_execution( functools.partial(format_event, event_id, publisher), settings_file, diff --git a/mobilizon_reshare/cli/publish_event/__init__.py b/mobilizon_reshare/cli/commands/__init__.py similarity index 100% rename from mobilizon_reshare/cli/publish_event/__init__.py rename to mobilizon_reshare/cli/commands/__init__.py diff --git a/mobilizon_reshare/cli/publish_recap/__init__.py b/mobilizon_reshare/cli/commands/format/__init__.py similarity index 100% rename from mobilizon_reshare/cli/publish_recap/__init__.py rename to mobilizon_reshare/cli/commands/format/__init__.py diff --git a/mobilizon_reshare/cli/format.py b/mobilizon_reshare/cli/commands/format/format.py similarity index 100% rename from mobilizon_reshare/cli/format.py rename to mobilizon_reshare/cli/commands/format/format.py diff --git a/mobilizon_reshare/cli/commands/inspect/__init__.py b/mobilizon_reshare/cli/commands/inspect/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mobilizon_reshare/cli/inspect_event.py b/mobilizon_reshare/cli/commands/inspect/inspect_event.py similarity index 100% rename from mobilizon_reshare/cli/inspect_event.py rename to mobilizon_reshare/cli/commands/inspect/inspect_event.py diff --git a/mobilizon_reshare/cli/commands/recap/__init__.py b/mobilizon_reshare/cli/commands/recap/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mobilizon_reshare/cli/commands/recap/main.py b/mobilizon_reshare/cli/commands/recap/main.py new file mode 100644 index 0000000..eda7bd5 --- /dev/null +++ b/mobilizon_reshare/cli/commands/recap/main.py @@ -0,0 +1,11 @@ +import logging.config + +from mobilizon_reshare.main.recap import recap + +logger = logging.getLogger(__name__) + + +async def main(): + + reports = await recap() + return 0 if reports and reports.successful else 1 diff --git a/mobilizon_reshare/cli/commands/start/__init__.py b/mobilizon_reshare/cli/commands/start/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mobilizon_reshare/cli/commands/start/main.py b/mobilizon_reshare/cli/commands/start/main.py new file mode 100644 index 0000000..ae3c123 --- /dev/null +++ b/mobilizon_reshare/cli/commands/start/main.py @@ -0,0 +1,10 @@ +from mobilizon_reshare.main.start import start + + +async def main(): + """ + STUB + :return: + """ + reports = await start() + return 0 if reports and reports.successful else 1 diff --git a/mobilizon_reshare/main/__init__.py b/mobilizon_reshare/main/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mobilizon_reshare/cli/publish_recap/main.py b/mobilizon_reshare/main/recap.py similarity index 89% rename from mobilizon_reshare/cli/publish_recap/main.py rename to mobilizon_reshare/main/recap.py index bab3a98..7edc559 100644 --- a/mobilizon_reshare/cli/publish_recap/main.py +++ b/mobilizon_reshare/main/recap.py @@ -1,5 +1,4 @@ -import logging.config -from typing import List +from typing import Optional, List from arrow import now @@ -9,6 +8,7 @@ from mobilizon_reshare.publishers.abstract import RecapPublication from mobilizon_reshare.publishers.coordinator import ( RecapCoordinator, PublicationFailureNotifiersCoordinator, + BaseCoordinatorReport, ) from mobilizon_reshare.publishers.platforms.platform_mapping import ( get_publisher_class, @@ -16,8 +16,6 @@ from mobilizon_reshare.publishers.platforms.platform_mapping import ( ) from mobilizon_reshare.storage.query import events_with_status -logger = logging.getLogger(__name__) - async def select_events_to_recap() -> List[MobilizonEvent]: return list( @@ -27,7 +25,7 @@ async def select_events_to_recap() -> List[MobilizonEvent]: ) -async def main(): +async def recap() -> Optional[BaseCoordinatorReport]: # I want to recap only the events that have been succesfully published and that haven't happened yet events_to_recap = await select_events_to_recap() if events_to_recap: @@ -44,7 +42,4 @@ async def main(): for report in reports.reports: if report.status == EventPublicationStatus.FAILED: PublicationFailureNotifiersCoordinator(report).notify_failure() - - return 0 if reports.successful else 1 - else: - return 0 + return reports diff --git a/mobilizon_reshare/cli/publish_event/main.py b/mobilizon_reshare/main/start.py similarity index 93% rename from mobilizon_reshare/cli/publish_event/main.py rename to mobilizon_reshare/main/start.py index f674324..0e56c01 100644 --- a/mobilizon_reshare/cli/publish_event/main.py +++ b/mobilizon_reshare/main/start.py @@ -1,4 +1,4 @@ -import logging.config +import logging from functools import partial from mobilizon_reshare.event.event_selection_strategies import select_event_to_publish @@ -20,12 +20,7 @@ from mobilizon_reshare.storage.query import ( logger = logging.getLogger(__name__) -async def main(): - """ - STUB - :return: - """ - +async def start(): # TODO: the logic to get published and unpublished events is probably redundant. # We need a simpler way to bring together events from mobilizon, unpublished events from the db # and published events from the DB @@ -62,7 +57,3 @@ async def main(): await save_publication_report(reports, waiting_publications_models) for report in reports.reports: PublicationFailureNotifiersCoordinator(report).notify_failure() - - return 0 if reports.successful else 1 - else: - return 0 diff --git a/mobilizon_reshare/publishers/coordinator.py b/mobilizon_reshare/publishers/coordinator.py index 22378e1..2976fd3 100644 --- a/mobilizon_reshare/publishers/coordinator.py +++ b/mobilizon_reshare/publishers/coordinator.py @@ -171,7 +171,7 @@ class AbstractNotifiersCoordinator(AbstractCoordinator): class PublicationFailureNotifiersCoordinator(AbstractNotifiersCoordinator): - def __init__(self, report: EventPublicationReport, platforms=None): + def __init__(self, report: BasePublicationReport, platforms=None): self.report = report super(PublicationFailureNotifiersCoordinator, self).__init__( message=report.get_failure_message(), notifiers=platforms @@ -187,7 +187,7 @@ class RecapCoordinator: def __init__(self, recap_publications: List[RecapPublication]): self.recap_publications = recap_publications - def run(self): + def run(self) -> BaseCoordinatorReport: reports = [] for recap_publication in self.recap_publications: try: