"""
General-(web-)purpose functions for use in your applications.
"""
import cgi
import urllib
import re
import datetime
__all__ = ['html_quote', 'url_quote', 'html_quote_whitespace']
def html_quote(v):
"""
HTML quote the value. None becomes an empty string. If a value
has an ``__html__`` method, that will be called to get the HTML.
"""
if v is None:
return ''
if hasattr(v, '__html__'):
return v.__html__()
if isinstance(v, basestring):
return cgi.escape(v, 1)
return cgi.escape(str(v), 1)
def url_quote(v):
"""
URL quote the value. None becomes the empty string. Dictionaries
are mapped to
"""
if isinstance(v, dict):
return urllib.urlencode(v)
elif v is None:
return ''
else:
return urllib.urlquote(str(v))
_whitespace_re = re.compile(r'[ ][ ]+')
def html_quote_whitespace(v, newlines=True, strip=True):
"""
HTML quote a value, and then make sure its whitespace is
preserved. If ``newlines`` is true, then also turn newlines into
``
`` -- otherwise just horizontal whitespace will be preserved
(using `` ``).
"""
v = html_quote(v)
if strip:
v = v.strip()
v = v.replace('\t', ' '*4)
if newlines:
lines = v.splitlines()
for i in range(len(lines)):
if lines[i].startswith(' '):
lines[i] = ' '+lines[i][1:]
v = '
\n'.join(lines)
v = _whitespace_re.sub(_sub_white, v)
return v
def _sub_white(m):
if len(m.group(0)) % 2:
return m.group(0).replace(' ', ' ')
else:
return ' '+' '*(len(m.group(0))/2)
def format_date_relative(date):
"""
Formats a date relative to the current time. The result
will be dates like 'Yesterday', 'Wednesday 10:00am',
'12 May 2003', etc.
Specifically:
* If in the last 24 hours, just give the time.
* If yesterday, give 'yesterday TIME'
* If in the last 7 days, give 'DAY_OF_WEEK TIME'
* If in the same calendar year, give 'DAY_OF_MONTH MONTH'
* Otherwise gives 'DAY_OF_MONTH MONTH YEAR'
It uses english names when appropriate (e.g., Apr or Thu).
"""
if date is None:
return ''
if isinstance(date, datetime.datetime):
now = datetime.datetime.now()
elif isinstance(date, datetime.date):
now = datetime.date.today()
else:
raise ValueError(
"Unknown type of date: %r" % date)
year = date.year
month = date.month
day = date.day
if now.year == year:
if now.month == month:
if (now - date) < datetime.timedelta(days=7):
if now.day == day:
return format_time(date)
elif now.day - 1 == day:
return 'Yest %s' % format_time(date)
else:
return date.strftime('%a ') + format_time(date)
elif (now - date) < datetime.timedelta(days=7):
return date.strftime('%a %d %b')
else:
return date.strftime('%d %b')
else:
return date.strftime('%d %b')
else:
return date.strftime('%d %b \'%y')
def format_time(t):
"""
Formats the time, like 4:20pm; unlike strftime, it lower-cases
the am/pm, and doesn't create hours with leading zeros.
"""
text = t.strftime('%I:%M%p')
text = text[:-2] + text[-2:].lower()
if text.startswith('0'):
text = text[1:]
return text