Source code for kadi.lib.format

# Copyright 2020 Karlsruhe Institute of Technology
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from datetime import timezone

from flask_babel import format_decimal
from flask_babel import gettext as _

from kadi.lib.utils import utcnow


[docs]def duration(seconds): """Create a human-readable, translated duration string from an amount of seconds. Note that locale-aware translations are only supported when having an active request context. :param seconds: The amount of seconds. :return: The formatted duration string. """ if seconds <= 0: return "0 {}".format(_("seconds")) units = [ (_("second"), _("seconds"), 60), (_("minute"), _("minutes"), 60), (_("hour"), _("hours"), 24), (_("day"), _("days"), 7), (_("week"), _("weeks"), None), ] result = "" current_value = new_value = seconds for singular, plural, factor in units: if factor is not None: new_value = current_value // factor current_value = current_value % factor if current_value > 0: unit = singular if current_value > 1: unit = plural result = f"{current_value} {unit}{', ' + result if result else ''}" current_value = new_value return result
[docs]def filesize(num_bytes): """Create a human-readable, localized file size from a given amount of bytes. Based on Jinja's ``filesizeformat`` filter. Note that locale-aware localization is only supported when having an active request context. :param num_bytes: The amount of bytes as a string or number. :return: The formatted file size string. """ num_bytes = int(float(num_bytes)) base = 1_000 if num_bytes == 1: return "1 Byte" if num_bytes < base: return f"{num_bytes} Bytes" unit = 1 for i, prefix in enumerate(["kB", "MB", "GB", "TB", "PB"]): unit = base ** (i + 2) if num_bytes < unit: break formatted_size = format_decimal(f"{base * num_bytes / unit:.1f}") return f"{formatted_size} {prefix}"
[docs]def timestamp(date_time=None, include_micro=False): """Build a UTC timestamp from a specific date and time. The timestamp will be in the form of ``"YYYYMMDDHHmmss"``. :param date_time: (optional) A datetime object as specified in Python's ``datetime`` module. Defaults to the current time. :param include_micro: (optional) Flag indicating whether to include microseconds in the timestamp as well or not. :return: The formatted timestamp string. """ fmt = "%Y%m%d%H%M%S" if include_micro: fmt += "%f" if date_time is None: date_time = utcnow() return date_time.astimezone(timezone.utc).strftime(fmt)
[docs]def pretty_type_name(cls_or_string): """Return a pretty type name based on a class or a string. :param cls_or_string: A class reference (e.g. ``str``) or a corresponding string (e.g. ``"str"``). :return: The pretty type name string. """ type_name = cls_or_string if not isinstance(type_name, str): type_name = type_name.__name__ if type_name == "str": return "string" if type_name == "int": return "integer" if type_name == "bool": return "boolean" if type_name == "dict": return "dictionary" return type_name