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
This commit is contained in:
Simone Robutti 2021-10-25 13:43:38 +02:00 committed by GitHub
parent 41e82f5035
commit bc61ad6123
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 74 additions and 43 deletions

View File

@ -1,18 +1,33 @@
import functools import functools
from enum import Enum
import click import click
from arrow import Arrow from arrow import Arrow
from click import pass_context from click import pass_context
from mobilizon_reshare.cli import safe_execution from mobilizon_reshare.cli import safe_execution
from mobilizon_reshare.cli.format import format_event from mobilizon_reshare.cli.commands.format.format import format_event
from mobilizon_reshare.cli.inspect_event import inspect_events from mobilizon_reshare.cli.commands.inspect.inspect_event import inspect_events
from mobilizon_reshare.cli.publish_event.main import main as start_main from mobilizon_reshare.cli.commands.start.main import main as start_main
from mobilizon_reshare.cli.publish_recap.main import main as recap_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 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( from_date_option = click.option(
"--begin", "--begin",
type=click.DateTime(), 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() @click.group()
def mobilizon_reshare(): def mobilizon_reshare():
pass pass
@mobilizon_reshare.command() @mobilizon_reshare.command(help="Synchronize and publish events")
@settings_file_option @settings_file_option
def start(settings_file): def start(settings_file):
safe_execution(start_main, settings_file=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 @settings_file_option
def recap(settings_file): def recap(settings_file):
safe_execution(recap_main, settings_file=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 @from_date_option
@to_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 @settings_file_option
@pass_context @pass_context
def inspect(ctx, target, begin, end, settings_file): def inspect(ctx, status, begin, end, settings_file):
ctx.ensure_object(dict) ctx.ensure_object(dict)
begin = Arrow.fromdatetime(begin) if begin else None begin = Arrow.fromdatetime(begin) if begin else None
end = Arrow.fromdatetime(end) if end 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( 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, 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 @settings_file_option
@click.argument("event-id", type=str) @click.argument("event-id", type=click.UUID)
@click.argument("publisher", type=str) @click.argument("publisher", type=click.Choice(publisher_names))
def format(settings_file, event_id, publisher): def format(settings_file, event_id, publisher):
safe_execution( safe_execution(
functools.partial(format_event, event_id, publisher), settings_file, functools.partial(format_event, event_id, publisher), settings_file,

View File

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

View File

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

View File

View File

@ -1,5 +1,4 @@
import logging.config from typing import Optional, List
from typing import List
from arrow import now from arrow import now
@ -9,6 +8,7 @@ from mobilizon_reshare.publishers.abstract import RecapPublication
from mobilizon_reshare.publishers.coordinator import ( from mobilizon_reshare.publishers.coordinator import (
RecapCoordinator, RecapCoordinator,
PublicationFailureNotifiersCoordinator, PublicationFailureNotifiersCoordinator,
BaseCoordinatorReport,
) )
from mobilizon_reshare.publishers.platforms.platform_mapping import ( from mobilizon_reshare.publishers.platforms.platform_mapping import (
get_publisher_class, get_publisher_class,
@ -16,8 +16,6 @@ from mobilizon_reshare.publishers.platforms.platform_mapping import (
) )
from mobilizon_reshare.storage.query import events_with_status from mobilizon_reshare.storage.query import events_with_status
logger = logging.getLogger(__name__)
async def select_events_to_recap() -> List[MobilizonEvent]: async def select_events_to_recap() -> List[MobilizonEvent]:
return list( 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 # 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() events_to_recap = await select_events_to_recap()
if events_to_recap: if events_to_recap:
@ -44,7 +42,4 @@ async def main():
for report in reports.reports: for report in reports.reports:
if report.status == EventPublicationStatus.FAILED: if report.status == EventPublicationStatus.FAILED:
PublicationFailureNotifiersCoordinator(report).notify_failure() PublicationFailureNotifiersCoordinator(report).notify_failure()
return reports
return 0 if reports.successful else 1
else:
return 0

View File

@ -1,4 +1,4 @@
import logging.config import logging
from functools import partial from functools import partial
from mobilizon_reshare.event.event_selection_strategies import select_event_to_publish 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__) logger = logging.getLogger(__name__)
async def main(): async def start():
"""
STUB
:return:
"""
# TODO: the logic to get published and unpublished events is probably redundant. # 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 # We need a simpler way to bring together events from mobilizon, unpublished events from the db
# and published 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) await save_publication_report(reports, waiting_publications_models)
for report in reports.reports: for report in reports.reports:
PublicationFailureNotifiersCoordinator(report).notify_failure() PublicationFailureNotifiersCoordinator(report).notify_failure()
return 0 if reports.successful else 1
else:
return 0

View File

@ -171,7 +171,7 @@ class AbstractNotifiersCoordinator(AbstractCoordinator):
class PublicationFailureNotifiersCoordinator(AbstractNotifiersCoordinator): class PublicationFailureNotifiersCoordinator(AbstractNotifiersCoordinator):
def __init__(self, report: EventPublicationReport, platforms=None): def __init__(self, report: BasePublicationReport, platforms=None):
self.report = report self.report = report
super(PublicationFailureNotifiersCoordinator, self).__init__( super(PublicationFailureNotifiersCoordinator, self).__init__(
message=report.get_failure_message(), notifiers=platforms message=report.get_failure_message(), notifiers=platforms
@ -187,7 +187,7 @@ class RecapCoordinator:
def __init__(self, recap_publications: List[RecapPublication]): def __init__(self, recap_publications: List[RecapPublication]):
self.recap_publications = recap_publications self.recap_publications = recap_publications
def run(self): def run(self) -> BaseCoordinatorReport:
reports = [] reports = []
for recap_publication in self.recap_publications: for recap_publication in self.recap_publications:
try: try: