mirror of
https://github.com/Tech-Workers-Coalition-Italia/mobilizon-reshare.git
synced 2025-01-29 00:29:40 +01:00
cli: inspect: Refactor command.
Now the inspect command can display informations about different kind of objects including events and publications. This patch also changes the cli to output columnar values suitable for further processing with standard Unix tool, such as awk. $ mobilizon-reshare.sh inspect publication -s completed | awk '{ print }' | sort | uniq -c [2021-12-01 01:05:55,321] [20] [INFO] Tortoise-ORM shutdown 2 mastodon 2 telegram 2 zulip
This commit is contained in:
parent
2d8855f6fe
commit
6f8f96d5b6
@ -1,26 +1,35 @@
|
||||
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.commands.format.format import format_event
|
||||
from mobilizon_reshare.cli.commands.inspect.inspect_event import inspect_events
|
||||
from mobilizon_reshare.cli.commands.inspect.inspect_publication import (
|
||||
inspect_publications,
|
||||
)
|
||||
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.config import current_version
|
||||
from mobilizon_reshare.config.publishers import publisher_names
|
||||
|
||||
from mobilizon_reshare.event.event import EventPublicationStatus
|
||||
from mobilizon_reshare.models.publication import PublicationStatus
|
||||
|
||||
status_name_to_enum = {
|
||||
"waiting": EventPublicationStatus.WAITING,
|
||||
"completed": EventPublicationStatus.COMPLETED,
|
||||
"failed": EventPublicationStatus.FAILED,
|
||||
"partial": EventPublicationStatus.PARTIAL,
|
||||
"all": None,
|
||||
"event": {
|
||||
"waiting": EventPublicationStatus.WAITING,
|
||||
"completed": EventPublicationStatus.COMPLETED,
|
||||
"failed": EventPublicationStatus.FAILED,
|
||||
"partial": EventPublicationStatus.PARTIAL,
|
||||
"all": None,
|
||||
},
|
||||
"publication": {
|
||||
"completed": PublicationStatus.COMPLETED,
|
||||
"failed": PublicationStatus.FAILED,
|
||||
"all": None,
|
||||
},
|
||||
}
|
||||
|
||||
settings_file_option = click.option(
|
||||
@ -41,6 +50,13 @@ to_date_option = click.option(
|
||||
expose_value=True,
|
||||
help="Include only events that begin before this datetime",
|
||||
)
|
||||
status_option = click.option(
|
||||
"-s",
|
||||
"--status",
|
||||
default="all",
|
||||
expose_value=True,
|
||||
help="Include only objects with the given status",
|
||||
)
|
||||
|
||||
|
||||
def print_version(ctx, param, value):
|
||||
@ -50,14 +66,6 @@ def print_version(ctx, param, value):
|
||||
ctx.exit()
|
||||
|
||||
|
||||
class InspectTarget(Enum):
|
||||
ALL = "all"
|
||||
WAITING = "waiting"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
|
||||
@click.group()
|
||||
@click.option(
|
||||
"--version", is_flag=True, callback=print_version, expose_value=False, is_eager=True
|
||||
@ -78,22 +86,25 @@ def recap(settings_file):
|
||||
safe_execution(recap_main, settings_file=settings_file)
|
||||
|
||||
|
||||
@mobilizon_reshare.command(help="Print events in the database that are in STATUS")
|
||||
@mobilizon_reshare.command(help="List objects in the database with different criteria")
|
||||
@from_date_option
|
||||
@to_date_option
|
||||
@click.argument(
|
||||
"status", type=click.Choice(list(status_name_to_enum.keys())),
|
||||
"object",
|
||||
type=click.Choice(list(status_name_to_enum.keys())),
|
||||
)
|
||||
@settings_file_option
|
||||
@pass_context
|
||||
def inspect(ctx, status, begin, end, settings_file):
|
||||
ctx.ensure_object(dict)
|
||||
@status_option
|
||||
def inspect(object, begin, end, settings_file, status):
|
||||
begin = Arrow.fromdatetime(begin) if begin else None
|
||||
end = Arrow.fromdatetime(end) if end else None
|
||||
|
||||
safe_execution(
|
||||
functools.partial(
|
||||
inspect_events, status_name_to_enum[status], frm=begin, to=end,
|
||||
inspect_events if object == "event" else inspect_publications,
|
||||
status_name_to_enum[object][status],
|
||||
frm=begin,
|
||||
to=end,
|
||||
),
|
||||
settings_file,
|
||||
)
|
||||
|
@ -27,8 +27,8 @@ def show_events(events: Iterable[MobilizonEvent]):
|
||||
|
||||
def pretty(event: MobilizonEvent):
|
||||
return (
|
||||
f"{event.name}\t{click.style(event.status.name, fg=status_to_color[event.status])}"
|
||||
f"\t{event.mobilizon_id}\t{event.begin_datetime.isoformat()}->{event.end_datetime.isoformat()}"
|
||||
f"{event.name : ^40}{click.style(event.status.name, fg=status_to_color[event.status]) : ^22}"
|
||||
f"{str(event.mobilizon_id) : <40}{event.begin_datetime.isoformat() : <29}{event.end_datetime.isoformat()}"
|
||||
)
|
||||
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
from typing import Iterable
|
||||
|
||||
import click
|
||||
from arrow import Arrow
|
||||
|
||||
from mobilizon_reshare.models.publication import Publication, PublicationStatus
|
||||
from mobilizon_reshare.storage.query.read import (
|
||||
get_all_publications,
|
||||
publications_with_status,
|
||||
)
|
||||
|
||||
status_to_color = {
|
||||
PublicationStatus.COMPLETED: "green",
|
||||
PublicationStatus.FAILED: "red",
|
||||
}
|
||||
|
||||
|
||||
def show_publications(publications: Iterable[Publication]):
|
||||
click.echo_via_pager("\n".join(map(pretty, publications)))
|
||||
|
||||
|
||||
def pretty(publication: Publication):
|
||||
return (
|
||||
f"{str(publication.id) : <40}{publication.timestamp.isoformat() : <36}"
|
||||
f"{click.style(publication.status.name, fg=status_to_color[publication.status]) : <22}"
|
||||
f"{publication.publisher.name : <12}{str(publication.event.id)}"
|
||||
)
|
||||
|
||||
|
||||
async def inspect_publications(
|
||||
status: PublicationStatus = None, frm: Arrow = None, to: Arrow = None
|
||||
):
|
||||
if status is None:
|
||||
publications = await get_all_publications(from_date=frm, to_date=to)
|
||||
else:
|
||||
publications = await publications_with_status(status, from_date=frm, to_date=to)
|
||||
|
||||
if publications:
|
||||
show_publications(list(publications))
|
||||
else:
|
||||
click.echo(f"No publication found with status: {status}")
|
@ -13,9 +13,7 @@ class Publication(Model):
|
||||
id = fields.UUIDField(pk=True)
|
||||
status = fields.IntEnumField(PublicationStatus)
|
||||
|
||||
# When a Publication's status is WAITING
|
||||
# we don't need a timestamp nor a reason
|
||||
timestamp = fields.DatetimeField(null=True)
|
||||
timestamp = fields.DatetimeField()
|
||||
reason = fields.TextField(null=True)
|
||||
|
||||
event = fields.ForeignKeyField("models.Event", related_name="publications")
|
||||
|
@ -55,6 +55,14 @@ async def events_with_status(
|
||||
)
|
||||
|
||||
|
||||
async def get_all_publications(
|
||||
from_date: Optional[Arrow] = None, to_date: Optional[Arrow] = None,
|
||||
) -> Iterable[Publication]:
|
||||
return await prefetch_publication_relations(
|
||||
_add_date_window(Publication.all(), "timestamp", from_date, to_date)
|
||||
)
|
||||
|
||||
|
||||
async def get_all_events(
|
||||
from_date: Optional[Arrow] = None, to_date: Optional[Arrow] = None,
|
||||
) -> Iterable[MobilizonEvent]:
|
||||
@ -74,6 +82,14 @@ async def prefetch_event_relations(queryset: QuerySet[Event]) -> list[Event]:
|
||||
)
|
||||
|
||||
|
||||
async def prefetch_publication_relations(queryset: QuerySet[Publication]) -> list[Publication]:
|
||||
return (
|
||||
await queryset.prefetch_related("publisher", "event")
|
||||
.order_by("timestamp")
|
||||
.distinct()
|
||||
)
|
||||
|
||||
|
||||
def _add_date_window(
|
||||
query,
|
||||
field_name: str,
|
||||
@ -93,7 +109,7 @@ async def publications_with_status(
|
||||
event_mobilizon_id: Optional[UUID] = None,
|
||||
from_date: Optional[Arrow] = None,
|
||||
to_date: Optional[Arrow] = None,
|
||||
) -> Publication:
|
||||
) -> Iterable[Publication]:
|
||||
query = Publication.filter(status=status)
|
||||
|
||||
if event_mobilizon_id:
|
||||
@ -101,9 +117,9 @@ async def publications_with_status(
|
||||
event__mobilizon_id=event_mobilizon_id
|
||||
)
|
||||
|
||||
query = _add_date_window(query, "timestamp", from_date, to_date)
|
||||
|
||||
return await query.prefetch_related("publisher").order_by("timestamp").distinct()
|
||||
return await prefetch_publication_relations(
|
||||
_add_date_window(query, "timestamp", from_date, to_date)
|
||||
)
|
||||
|
||||
|
||||
async def events_without_publications(
|
||||
|
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
@ -18,6 +19,7 @@ from mobilizon_reshare.publishers.coordinator import (
|
||||
PublicationFailureNotifiersCoordinator,
|
||||
RecapCoordinator,
|
||||
)
|
||||
from tests import today
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
@ -91,7 +93,7 @@ async def mock_publications(
|
||||
id=UUID(int=i + 1),
|
||||
event=event,
|
||||
publisher=publisher,
|
||||
timestamp=None,
|
||||
timestamp=today + timedelta(hours=i),
|
||||
reason=None,
|
||||
)
|
||||
publication = EventPublication.from_orm(publication, test_event)
|
||||
|
Loading…
x
Reference in New Issue
Block a user