Splitted up utils
This commit is contained in:
		
							
								
								
									
										87
									
								
								nxy/utils.py
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								nxy/utils.py
									
									
									
									
									
								
							@@ -1,87 +0,0 @@
 | 
				
			|||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
import re
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from datetime import datetime, timedelta
 | 
					 | 
				
			||||||
from pprint import pprint
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# @formatter:off
 | 
					 | 
				
			||||||
COLORS = dict(
 | 
					 | 
				
			||||||
    white=0,    # white
 | 
					 | 
				
			||||||
    black=1,    # black
 | 
					 | 
				
			||||||
    blue=2,     # blue (navy)
 | 
					 | 
				
			||||||
    green=3,    # green
 | 
					 | 
				
			||||||
    red=4,      # red
 | 
					 | 
				
			||||||
    maroon=5,   # brown (maroon)
 | 
					 | 
				
			||||||
    purple=6,   # purple
 | 
					 | 
				
			||||||
    orange=7,   # orange (olive)
 | 
					 | 
				
			||||||
    yellow=8,   # yellow
 | 
					 | 
				
			||||||
    ltgreen=9,  # light green (lime)
 | 
					 | 
				
			||||||
    teal=10,    # teal (a green/blue cyan)
 | 
					 | 
				
			||||||
    ltcyan=11,  # light cyan (cyan / aqua)
 | 
					 | 
				
			||||||
    ltblue=12,  # light blue (royal)
 | 
					 | 
				
			||||||
    pink=13,    # pink (light purple / fuchsia)
 | 
					 | 
				
			||||||
    grey=14,    # grey
 | 
					 | 
				
			||||||
    ltgrey=15,  # light grey (silver)
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FORMATTING = dict(
 | 
					 | 
				
			||||||
    bold='\x02',       # bold
 | 
					 | 
				
			||||||
    color='\x03',      # colored text
 | 
					 | 
				
			||||||
    italic='\x1D',     # italic text
 | 
					 | 
				
			||||||
    underline='\x1F',  # underlined text
 | 
					 | 
				
			||||||
    swap='\x16',       # swap bg and fg colors ("reverse video")
 | 
					 | 
				
			||||||
    reset='\x0F',      # reset all formatting
 | 
					 | 
				
			||||||
    **COLORS
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
# @formatter:on
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Debug helper
 | 
					 | 
				
			||||||
pp = pprint
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def fmt(__text: str, **kwargs) -> str:
 | 
					 | 
				
			||||||
    """Formats a str with `kwargs` and `FORMATTING`."""
 | 
					 | 
				
			||||||
    return __text.format(**kwargs, **FORMATTING)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def date_from_iso(date: str) -> datetime:
 | 
					 | 
				
			||||||
    return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def time_delta(text: str) -> timedelta:
 | 
					 | 
				
			||||||
    match = re.match(r'(\d+)(s|m|h|mon|w|y)', text)
 | 
					 | 
				
			||||||
    if match:
 | 
					 | 
				
			||||||
        num, unit = match.groups()
 | 
					 | 
				
			||||||
        num = int(num)
 | 
					 | 
				
			||||||
        if unit == 's':
 | 
					 | 
				
			||||||
            unit = 'seconds'
 | 
					 | 
				
			||||||
        elif unit == 'm':
 | 
					 | 
				
			||||||
            unit = 'minutes'
 | 
					 | 
				
			||||||
        elif unit == 'h':
 | 
					 | 
				
			||||||
            unit = 'hours'
 | 
					 | 
				
			||||||
        elif unit == 'd':
 | 
					 | 
				
			||||||
            unit = 'days'
 | 
					 | 
				
			||||||
        elif unit == 'w':
 | 
					 | 
				
			||||||
            unit = 'weeks'
 | 
					 | 
				
			||||||
        elif unit == 'mon':
 | 
					 | 
				
			||||||
            unit = 'weeks'
 | 
					 | 
				
			||||||
            num *= 4
 | 
					 | 
				
			||||||
        elif unit == 'y':
 | 
					 | 
				
			||||||
            unit = 'weeks'
 | 
					 | 
				
			||||||
            num *= 52
 | 
					 | 
				
			||||||
        return timedelta(**{unit: num})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def parse_int(val: str) -> tuple:
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        val = int(val)
 | 
					 | 
				
			||||||
        if val is not 0:
 | 
					 | 
				
			||||||
            if val < 1:
 | 
					 | 
				
			||||||
                order, op = 'desc', '<='
 | 
					 | 
				
			||||||
                val *= -1
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                order, op = 'asc', '>='
 | 
					 | 
				
			||||||
            val -= 1
 | 
					 | 
				
			||||||
            return val, order, op
 | 
					 | 
				
			||||||
    except ValueError:
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
							
								
								
									
										20
									
								
								nxy/utils/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								nxy/utils/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					from pprint import pprint as pp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .date import date_from_iso, time_delta, time_since
 | 
				
			||||||
 | 
					from .formatting import fmt, FORMATTING
 | 
				
			||||||
 | 
					from .misc import parse_int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__all__ = (
 | 
				
			||||||
 | 
					    # pprint alias
 | 
				
			||||||
 | 
					    'pp',
 | 
				
			||||||
 | 
					    # date and time stuff
 | 
				
			||||||
 | 
					    'date_from_iso',
 | 
				
			||||||
 | 
					    'time_delta',
 | 
				
			||||||
 | 
					    'time_since',
 | 
				
			||||||
 | 
					    # formatting
 | 
				
			||||||
 | 
					    'fmt',
 | 
				
			||||||
 | 
					    'FORMATTING',
 | 
				
			||||||
 | 
					    # misc
 | 
				
			||||||
 | 
					    'parse_int'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										84
									
								
								nxy/utils/date.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								nxy/utils/date.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from datetime import datetime, timedelta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def date_from_iso(date: str) -> datetime:
 | 
				
			||||||
 | 
					    return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def time_delta(text: str) -> timedelta:
 | 
				
			||||||
 | 
					    match = re.match(r'(\d+)(s|m|h|mon|w|y)', text)
 | 
				
			||||||
 | 
					    if match:
 | 
				
			||||||
 | 
					        num, unit = match.groups()
 | 
				
			||||||
 | 
					        num = int(num)
 | 
				
			||||||
 | 
					        if unit == 's':
 | 
				
			||||||
 | 
					            unit = 'seconds'
 | 
				
			||||||
 | 
					        elif unit == 'm':
 | 
				
			||||||
 | 
					            unit = 'minutes'
 | 
				
			||||||
 | 
					        elif unit == 'h':
 | 
				
			||||||
 | 
					            unit = 'hours'
 | 
				
			||||||
 | 
					        elif unit == 'd':
 | 
				
			||||||
 | 
					            unit = 'days'
 | 
				
			||||||
 | 
					        elif unit == 'w':
 | 
				
			||||||
 | 
					            unit = 'weeks'
 | 
				
			||||||
 | 
					        elif unit == 'mon':
 | 
				
			||||||
 | 
					            unit = 'weeks'
 | 
				
			||||||
 | 
					            num *= 4
 | 
				
			||||||
 | 
					        elif unit == 'y':
 | 
				
			||||||
 | 
					            unit = 'weeks'
 | 
				
			||||||
 | 
					            num *= 52
 | 
				
			||||||
 | 
					        return timedelta(**{unit: num})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def time_since(date: datetime, now: datetime = None):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Takes two datetime objects and returns the time between d and now
 | 
				
			||||||
 | 
					    as a nicely formatted string, e.g. "10 minutes".  If d occurs after now,
 | 
				
			||||||
 | 
					    then "0 minutes" is returned.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Units used are years, months, weeks, days, hours, and minutes.
 | 
				
			||||||
 | 
					    Seconds and microseconds are ignored.  Up to two adjacent units will be
 | 
				
			||||||
 | 
					    displayed.  For example, "2 weeks, 3 days" and "1 year, 3 months" are
 | 
				
			||||||
 | 
					    possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    chunks = (
 | 
				
			||||||
 | 
					        (60 * 60 * 24 * 365, ('year', 'years')),
 | 
				
			||||||
 | 
					        (60 * 60 * 24 * 30, ('month', 'months')),
 | 
				
			||||||
 | 
					        (60 * 60 * 24 * 7, ('week', 'weeks')),
 | 
				
			||||||
 | 
					        (60 * 60 * 24, ('day', 'days')),
 | 
				
			||||||
 | 
					        (60 * 60, ('hour', 'hours')),
 | 
				
			||||||
 | 
					        (60, ('minute', 'minutes'))
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if not now:
 | 
				
			||||||
 | 
					        now = datetime.now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # ignore microsecond part of 'd' since we removed it from 'now'
 | 
				
			||||||
 | 
					    delta = now - (date - timedelta(0, 0, date.microsecond))
 | 
				
			||||||
 | 
					    since = delta.days * 24 * 60 * 60 + delta.seconds
 | 
				
			||||||
 | 
					    if since <= 0:
 | 
				
			||||||
 | 
					        # d is in the future compared to now, stop processing.
 | 
				
			||||||
 | 
					        return u'0 ' + 'minutes'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    name = None
 | 
				
			||||||
 | 
					    count = None
 | 
				
			||||||
 | 
					    seconds = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for i, (seconds, name) in enumerate(chunks):
 | 
				
			||||||
 | 
					        count = since // seconds
 | 
				
			||||||
 | 
					        if count != 0:
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s = '%(number)d %(type)s' % {'number': count, 'type': name[count != 1]}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if i + 1 < len(chunks):
 | 
				
			||||||
 | 
					        # Now get the second item
 | 
				
			||||||
 | 
					        seconds2, name2 = chunks[i + 1]
 | 
				
			||||||
 | 
					        count2 = (since - (seconds * count)) // seconds2
 | 
				
			||||||
 | 
					        if count2 != 0:
 | 
				
			||||||
 | 
					            s += ', %d %s' % (count2, name2[count2 != 1])
 | 
				
			||||||
 | 
					    return s
 | 
				
			||||||
							
								
								
									
										38
									
								
								nxy/utils/formatting.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								nxy/utils/formatting.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# @formatter:off
 | 
				
			||||||
 | 
					COLORS = {
 | 
				
			||||||
 | 
					    'white': 0,    # white
 | 
				
			||||||
 | 
					    'black': 1,    # black
 | 
				
			||||||
 | 
					    'blue': 2,     # blue (navy)
 | 
				
			||||||
 | 
					    'green': 3,    # green
 | 
				
			||||||
 | 
					    'red': 4,      # red
 | 
				
			||||||
 | 
					    'maroon': 5,   # brown (maroon)
 | 
				
			||||||
 | 
					    'purple': 6,   # purple
 | 
				
			||||||
 | 
					    'orange': 7,   # orange (olive)
 | 
				
			||||||
 | 
					    'yellow': 8,   # yellow
 | 
				
			||||||
 | 
					    'ltgreen': 9,  # light green (lime)
 | 
				
			||||||
 | 
					    'teal': 10,    # teal (a green/blue cyan)
 | 
				
			||||||
 | 
					    'ltcyan': 11,  # light cyan (cyan / aqua)
 | 
				
			||||||
 | 
					    'ltblue': 12,  # light blue (royal)
 | 
				
			||||||
 | 
					    'pink': 13,    # pink (light purple / fuchsia)
 | 
				
			||||||
 | 
					    'grey': 14,    # grey
 | 
				
			||||||
 | 
					    'ltgrey': 15,  # light grey (silver)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FORMATTING = {
 | 
				
			||||||
 | 
					    'bold': '\x02',       # bold
 | 
				
			||||||
 | 
					    'color': '\x03',      # colored text
 | 
				
			||||||
 | 
					    'italic': '\x1D',     # italic text
 | 
				
			||||||
 | 
					    'underline': '\x1F',  # underlined text
 | 
				
			||||||
 | 
					    'swap': '\x16',       # swap bg and fg colors ("reverse video")
 | 
				
			||||||
 | 
					    'reset': '\x0F',      # reset all formatting
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FORMATTING.update(COLORS)
 | 
				
			||||||
 | 
					# @formatter:on
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def fmt(__text: str, **kwargs) -> str:
 | 
				
			||||||
 | 
					    """Formats a str with `kwargs` and `FORMATTING`."""
 | 
				
			||||||
 | 
					    return __text.format(**kwargs, **FORMATTING)
 | 
				
			||||||
							
								
								
									
										17
									
								
								nxy/utils/misc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								nxy/utils/misc.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def parse_int(val: str, select: bool = True) -> tuple:
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        val = int(val)
 | 
				
			||||||
 | 
					        if val is not 0:
 | 
				
			||||||
 | 
					            if val < 1:
 | 
				
			||||||
 | 
					                order, op = 'desc', '<='
 | 
				
			||||||
 | 
					                val *= -1
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                order, op = 'asc', '>='
 | 
				
			||||||
 | 
					            if select:
 | 
				
			||||||
 | 
					                val -= 1
 | 
				
			||||||
 | 
					            return val, order, op
 | 
				
			||||||
 | 
					    except ValueError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
		Reference in New Issue
	
	Block a user