Skip to content
Snippets Groups Projects
Select Git revision
  • ba8265f032bb1cfc4f06e549d75103e6cd4b4557
  • devel default
  • master
  • fo
  • jirka/typing
  • fo-base
  • mj/submit-images
  • jk/issue-96
  • jk/issue-196
  • honza/add-contestant
  • honza/mr7
  • honza/mrf
  • honza/mrd
  • honza/mra
  • honza/mr6
  • honza/submit-images
  • honza/kolo-vs-soutez
  • jh-stress-test-wip
  • shorten-schools
19 results

rights.py

Blame
  • util_format.py 4.24 KiB
    # Utils that do not depend on any other in mo (to avoid circular dependency)
    
    from datetime import datetime
    import decimal
    from typing import Optional
    
    import mo
    
    
    def inflect_number(n: int, w1: str, w234: str, wother: str, unitprefix: str = '') -> str:
        if n == 1:
            return f'{n} {unitprefix}{w1}'
        elif 2 <= n <= 4:
            return f'{n} {unitprefix}{w234}'
        else:
            return f'{n} {unitprefix}{wother}'
    
    
    def inflect_by_number(n: int, w1: str, w234: str, wother: str, unitprefix: str = '') -> str:
        if n == 1:
            return f'{unitprefix}{w1}'
        elif 2 <= n <= 4:
            return f'{unitprefix}{w234}'
        else:
            return f'{unitprefix}{wother}'
    
    
    def inflect_with_number(n: int, w1: str, w234: str, wother: str) -> str:
        if n == 1:
            return w1 % n
        elif 2 <= n <= 4:
            return w234 % n
        else:
            return wother % n
    
    
    def timeformat(dt: datetime) -> str:
        if dt is None:
            return ''
        else:
            return dt.astimezone().strftime("%Y-%m-%d %H:%M")
    
    
    def timeformat_short(dt: datetime) -> str:
        if dt is None:
            return ''
        else:
            return dt.astimezone().strftime("%Y-%m-%d")
    
    
    def timedelta(d: datetime, ref: Optional[datetime] = None, descriptive: bool = False) -> str:
        """Vyrábí česky formátované řetězece 'za 3 minuty', 'před 27 dny' a podobně
        z rozdílu daného datetime a referenčního času (například now).
        Pokud se předá `descriptive=True`, tak vyrábí "deskriptivní" popis
        ve stylu '3 minuty po', '27 dní před' a podobně.
        """
        if ref is None:
            ref = mo.now
        (prefix, suffix) = ("", "")
        if ref > d:
            delta = ref - d
            if descriptive:
                suffix = " před"
            else:
                prefix = "před "
            before = True
        else:
            delta = d - ref
            if descriptive:
                suffix = " po"
            else:
                prefix = "za "
            before = False
    
        # Zkonstruujeme nejvýše dvě části: pokud je v první číslo >= 10, další už
        # nekonstruujeme, pokud je <10, tak přidáme ještě jednu část. Tvoříme tedy
        # řetězce jako: "za 28 dní", "za 8 dní 16 hodin", "za 7 hodin 55 minut",
        # "za 55 minut", "za 3 minuty 12 sekund", ...
        parts = []
        prev = 0
        if delta.days > 0:
            if before:
                parts.append(inflect_number(delta.days, 'den' if descriptive else 'dnem', 'dny', 'dny'))
            else:
                parts.append(inflect_number(delta.days, 'den', 'dny', 'dní'))
            prev = delta.days
    
        seconds = delta.seconds
        for (unitprefix, s) in [('hodin', 3600), ('minut', 60), ('sekund', 1)]:
            number = seconds // s
            seconds = seconds % s
            if len(parts) == 2 or (len(parts) == 1 and number == 0) or prev >= 10:
                break
            if number == 0:
                continue
            prev = number
            if before:
                # 1 minuta před, 3 minuty před, 5 minut před / před 1 minutou, před 3 minutami, před 5 minutami
                if descriptive:
                    parts.append(inflect_number(number, 'a', 'y', '', unitprefix=unitprefix))
                else:
                    parts.append(inflect_number(number, 'ou', 'ami', 'ami', unitprefix=unitprefix))
            else:
                # 1 minuta po, 3 minuty po, 5 minut po / za 1 minutu, za 3 minuty, za 5 minut
                parts.append(inflect_number(number, 'a' if descriptive else 'u', 'y', '', unitprefix=unitprefix))
    
        if len(parts) == 0:
            if before and not descriptive:
                parts.append("méně než sekundou")
            else:
                parts.append("méně než sekundu")
        value = " ".join(parts)
        return f"{prefix}{value}{suffix}"
    
    
    def time_and_timedelta(d: datetime, ref: Optional[datetime] = None) -> str:
        if d is None:
            return ''
        return f"{timeformat(d)} ({timedelta(d, ref)})"
    
    
    def data_size(bytes: int) -> str:
        if bytes is None:
            return '0 B'
        elif bytes >= 1 << 30:
            return f'{bytes/(1<<30):.1f} GiB'
        elif bytes >= 1 << 20:
            return f'{bytes/(1<<20):.1f} MiB'
        else:
            return f'{bytes/(1<<10):.1f} KiB'
    
    
    def format_decimal(points: Optional[decimal.Decimal]) -> Optional[str]:
        if points is None:
            return None
        elif points % 1 == 0:
            return str(int(points))
        else:
            return str(points)