Splitted up utils

This commit is contained in:
mrhanky 2017-05-29 14:38:51 +02:00
parent 99afe042cd
commit 74a4129afd
No known key found for this signature in database
GPG Key ID: 67D772C481CB41B8
5 changed files with 159 additions and 87 deletions

View File

@ -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
View 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
View 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
View 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
View 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