
    DhE              	          d Z ddlZddlmZ dedefdZ	 ddej                  egef   dej                  d	ej                  dej                  fd
Z		 ddej                  ej                  ej                  f   dedefdZy)aT  
This module provides utility functions for formatting strings and dates.

Functions:
    camel_to_underscore(name: str) -> str:
        Convert camel case style naming to underscore/snake case style naming.

    apply_recursive(function: Callable[[str], str], data: OptionalScope = None,
                    **kwargs: Any) -> OptionalScope:
        Apply a function to all keys in a scope recursively.

    timesince(dt: Union[datetime.datetime, datetime.timedelta],
              default: str = 'just now') -> str:
        Returns string representing 'time since' e.g. 3 days ago, 5 hours ago.
    N)typesnamereturnc                    g }t        |       D ]  \  }}|dkD  r| |dz
     }|j                         r'|j                         s|dk7  r|j                  d       n[|dkD  rV|j                         sF| |dz
  | }|j                         r.|j                         r|j	                  t        |      dz
  d       |j                  |j                                 dj                  |      S )af  Convert camel case style naming to underscore/snake case style naming.

    If there are existing underscores they will be collapsed with the
    to-be-added underscores. Multiple consecutive capital letters will not be
    split except for the last one.

    >>> camel_to_underscore('SpamEggsAndBacon')
    'spam_eggs_and_bacon'
    >>> camel_to_underscore('Spam_and_bacon')
    'spam_and_bacon'
    >>> camel_to_underscore('Spam_And_Bacon')
    'spam_and_bacon'
    >>> camel_to_underscore('__SpamAndBacon__')
    '__spam_and_bacon__'
    >>> camel_to_underscore('__SpamANDBacon__')
    '__spam_and_bacon__'
    r      _    )	enumerateisupperappendisalphainsertlenlowerjoin)r   outputicpcpreviouss         y/var/www/fastuser/data/www/generator.snapmosaic.io/flask_app/venv/lib/python3.12/site-packages/python_utils/formatters.pycamel_to_underscorer      s    $ !F$ !1q5a!eByy{2::<B#I c"Qqyy{  A?##%(*:*:*<MM#f+/37aggi !  776?    functiondatakwargsc           
          |yt        |t              r5|j                         D ci c]  \  }} | |      t        | |fi | c}}S |S c c}}w )a  
    Apply a function to all keys in a scope recursively.

    >>> apply_recursive(camel_to_underscore, {'SpamEggsAndBacon': 'spam'})
    {'spam_eggs_and_bacon': 'spam'}
    >>> apply_recursive(
    ...     camel_to_underscore,
    ...     {
    ...         'SpamEggsAndBacon': {
    ...             'SpamEggsAndBacon': 'spam',
    ...         }
    ...     },
    ... )
    {'spam_eggs_and_bacon': {'spam_eggs_and_bacon': 'spam'}}

    >>> a = {'a_b_c': 123, 'def': {'DeF': 456}}
    >>> b = apply_recursive(camel_to_underscore, a)
    >>> b
    {'a_b_c': 123, 'def': {'de_f': 456}}

    >>> apply_recursive(camel_to_underscore, None)
    N)
isinstancedictitemsapply_recursive)r   r   r   keyvalues        r   r"   r"   =   s^    6 |	D$	 #jjl
U SM?8UEfEE
 	

 
s   Adtdefaultc           	      h   t        | t        j                        r| }n,t        j                  j                         }t	        || z
        }|j
                  dz  ddf|j
                  dz  dz  ddf|j
                  dz  dz  dd	f|j
                  dz  d
df|j                  dz  ddf|j                  dz  dz  ddf|j                  dz  ddff}g }|D ]F  \  }}}t        |      }	|	dk(  r|j                  |	 d|        .|	s1|j                  |	 d|        H |rdj                  |dd        dS |S )aG  
    Returns string representing 'time since' e.g.
    3 days ago, 5 hours ago etc.

    >>> now = datetime.datetime.now()
    >>> timesince(now)
    'just now'
    >>> timesince(now - datetime.timedelta(seconds=1))
    '1 second ago'
    >>> timesince(now - datetime.timedelta(seconds=2))
    '2 seconds ago'
    >>> timesince(now - datetime.timedelta(seconds=60))
    '1 minute ago'
    >>> timesince(now - datetime.timedelta(seconds=61))
    '1 minute and 1 second ago'
    >>> timesince(now - datetime.timedelta(seconds=62))
    '1 minute and 2 seconds ago'
    >>> timesince(now - datetime.timedelta(seconds=120))
    '2 minutes ago'
    >>> timesince(now - datetime.timedelta(seconds=121))
    '2 minutes and 1 second ago'
    >>> timesince(now - datetime.timedelta(seconds=122))
    '2 minutes and 2 seconds ago'
    >>> timesince(now - datetime.timedelta(seconds=3599))
    '59 minutes and 59 seconds ago'
    >>> timesince(now - datetime.timedelta(seconds=3600))
    '1 hour ago'
    >>> timesince(now - datetime.timedelta(seconds=3601))
    '1 hour and 1 second ago'
    >>> timesince(now - datetime.timedelta(seconds=3602))
    '1 hour and 2 seconds ago'
    >>> timesince(now - datetime.timedelta(seconds=3660))
    '1 hour and 1 minute ago'
    >>> timesince(now - datetime.timedelta(seconds=3661))
    '1 hour and 1 minute ago'
    >>> timesince(now - datetime.timedelta(seconds=3720))
    '1 hour and 2 minutes ago'
    >>> timesince(now - datetime.timedelta(seconds=3721))
    '1 hour and 2 minutes ago'
    >>> timesince(datetime.timedelta(seconds=3721))
    '1 hour and 2 minutes ago'
    im  yearyears   monthmonths   weekweeksdaydaysi  hourhours<   minuteminutessecondsecondsr    z and N   z ago)
r   datetime	timedeltanowabsr1   r8   intr   r   )
r%   r&   diffr=   periodsr   periodsingularplural
int_periods
             r   	timesincerF   d   sY   \ "h(()##%38} 
S&'*	S2	w1	R!	VW-	Qv&		fg.		r	!8Y7		Hi0G !F$+ 4 &[
?MMZL(45MMZL&234 ,,vbqz*+400Nr   )N)zjust now)__doc__r;   python_utilsr   strr   CallableOptionalScopeAnyr"   Unionr<   rF    r   r   <module>rO      s   "  #c #c #P !%$nncUCZ($


$ ii$ 	$R IH%%x'9'99:II 	Ir   