"""Utilities for githubcap project."""
import datetime
import json
import logging
import re
import typing
import click
import attr
import daiquiri
_DATETIME_ISO_8601 = "%Y-%m-%dT%H:%M:%SZ"
_PAGINATION_RE = re.compile(r'.*[?!]page=(\d+).*')
_DEFAULT_NO_COLOR_FORMAT = "%(asctime)s [%(process)d] %(levelname)-8.8s %(name)s: %(message)s"
_DEFAULT_COLOR_FORMAT = "%(asctime)s [%(process)d] %(color)s%(levelname)-8.8s %(name)s: %(message)s%(color_stop)s"
[docs]def parse_datetime(datetime_string: str) -> datetime.datetime:
"""Parse ISO-8601 datetime representation."""
return datetime.datetime.strptime(datetime_string, _DATETIME_ISO_8601) if datetime_string is not None else None
[docs]def serialize_datetime(datetime_instance: datetime.datetime) -> str:
"""Serialize ISO-8601 datetime representation."""
return datetime_instance.strftime(_DATETIME_ISO_8601) if datetime_instance is not None else None
[docs]def setup_logging(verbose: int, no_color: bool) -> None:
"""Set up logging facilities.
:param verbose: verbosity level
:param no_color: do not use color in output
"""
level = logging.WARNING
if verbose == 1:
level = logging.INFO
elif verbose > 1:
level = logging.DEBUG
formatter = daiquiri.formatter.ColorFormatter(fmt=_DEFAULT_COLOR_FORMAT)
if no_color:
formatter = logging.Formatter(fmt=_DEFAULT_NO_COLOR_FORMAT)
daiquiri.setup(level=level, outputs=(
daiquiri.output.Stream(formatter=formatter),
))
[docs]def dict2json(dict_: dict, pretty: bool = True) -> str:
"""Convert dict to json (string).
:param dict_: dictionary to be converted
:param pretty: if True, nice formatting will be used
:return: formatted dict in json
"""
kwargs = {}
if pretty:
kwargs['sort_keys'] = True
kwargs['separators'] = (',', ': ')
kwargs['indent'] = 2
return json.dumps(dict_, **kwargs)
[docs]def print_command_result(result: dict, pretty=True) -> None:
"""Print results.
:param result: a result to be printed
:param pretty: print result in a pretty way
:type pretty: bool
"""
result = dict2json(result, pretty=pretty)
click.echo("{!s}".format(result))
[docs]def get_attr_type(class_: type, attr_name: str) -> type:
"""Get type of attribute in a attr class."""
return getattr(attr.fields(class_), attr_name).type
[docs]def get_option_choices(class_: type, attr_name: str) -> typing.List[str]:
"""Get all choices for an enum."""
return get_attr_type(class_, attr_name).all_names()
[docs]def command_choice_callback(enum: type, _, param, value) -> type: # pylint: disable=unused-argument
"""Translate the given value to enum representation."""
if value is None:
return None
return getattr(enum, value)